Skip to content

Commit d22b4e2

Browse files
committed
Update draggame to use never node modules
Game is done with Copilot
1 parent 89f9366 commit d22b4e2

5 files changed

Lines changed: 256 additions & 123 deletions

File tree

atest/test/02_Content_Keywords/solve_draggame.robot

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@ Resource imports.resource
33

44
Test Setup New Page ${DRAGGAME_URL}
55

6-
Force Tags no-iframe
7-
86
*** Test Cases ***
97
Move Obstacle To Goal And Make A Goal
108
Get Text h2 == Put the circle in the goal
11-
Drag And Drop css=.obstacle css=.goal
12-
Drag And Drop css=.circle css=.goal
13-
Get Text h2 == GOAL!!
9+
Drag And Drop id=blue-box id=invisible-element steps=10
10+
Drag And Drop id=red-circle id=goal steps=10
11+
Get Text h2 == GOAL!!!
1412

1513
Move Obstacle Away And Drag And Drop
16-
Hover "Obstacle"
14+
Get Text h2 == Put the circle in the goal
15+
Hover id=blue-box
1716
Mouse Button down
18-
Mouse Move Relative To "Obstacle" 500
17+
Mouse Move Relative To id=blue-box 200
1918
Mouse Button up
20-
Drag And Drop "Circle" "Goal"
19+
Drag And Drop id=red-circle id=goal steps=10
20+
Get Text h2 == GOAL!!!
2121

2222
Test
2323
[Tags] slow

node/dynamic-test-app/src/app.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DragGame } from './draggame';
1+
import DragGame from './draggame';
22
import { HashRouter, Route, Routes } from 'react-router-dom';
33
import Login from './login';
44
import React from 'react';
Lines changed: 151 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,155 @@
1-
import Draggable, { DraggableData, DraggableEvent } from 'react-draggable';
2-
import React, { useState } from 'react';
1+
// Created by Copilot
2+
// This code is a simple drag-and-drop game using React and react-dnd.
3+
import React, { useState, useEffect } from "react";
4+
import { DndProvider, useDrag, useDrop } from "react-dnd";
5+
import { HTML5Backend } from "react-dnd-html5-backend";
36

4-
// Remove after fix:
5-
// https://github.com/react-grid-layout/react-draggable/pull/648#issuecomment-1100110050
6-
declare module 'react-draggable' {
7-
export interface DraggableProps {
8-
children: React.ReactNode;
9-
}
10-
}
7+
const ItemTypes = {
8+
CIRCLE: "circle",
9+
BOX: "box",
10+
};
1111

12-
export function DragGame() {
13-
const goal = {
14-
top: 500,
15-
left: 100,
16-
width: 130,
17-
height: 130,
18-
};
19-
const onCircleDrag = (e: DraggableEvent, position: DraggableData) => {
20-
const { x, y } = position;
21-
if (y >= 430 && y <= 465 && x >= 95 && x <= 130) {
22-
setCircleInTheGoal(true);
12+
const DraggableItem = ({ id, type, x, y }) => {
13+
const [{ isDragging }, drag] = useDrag(() => ({
14+
type,
15+
item: { id, type },
16+
collect: (monitor) => ({
17+
isDragging: monitor.isDragging(),
18+
}),
19+
}));
20+
21+
return (
22+
<div
23+
id={type === ItemTypes.CIRCLE ? "red-circle" : "blue-box"} // Add id for red circle and blue box
24+
ref={drag}
25+
style={{
26+
position: "absolute",
27+
left: x,
28+
top: y,
29+
width: type === ItemTypes.CIRCLE ? 50 : 160, // Doubled width for blue box
30+
height: type === ItemTypes.CIRCLE ? 50 : 160, // Doubled height for blue box
31+
backgroundColor: type === ItemTypes.CIRCLE ? "red" : "blue",
32+
borderRadius: type === ItemTypes.CIRCLE ? "50%" : "0",
33+
opacity: isDragging ? 0.5 : 1,
34+
cursor: "move",
35+
}}
36+
/>
37+
);
38+
};
39+
40+
const DropZone = ({ onDrop, onGoal }) => {
41+
const [, drop] = useDrop(() => ({
42+
accept: [ItemTypes.CIRCLE, ItemTypes.BOX],
43+
drop: (item, monitor) => {
44+
const offset = monitor.getClientOffset();
45+
if (offset) {
46+
const isInGoal =
47+
offset.x >= 300 &&
48+
offset.x <= 400 &&
49+
offset.y >= 300 &&
50+
offset.y <= 400;
51+
52+
if (isInGoal && item.type === ItemTypes.CIRCLE) {
53+
onGoal();
54+
} else {
55+
onDrop(item.id, offset.x, offset.y);
2356
}
24-
setCirclePosition({ x, y });
25-
};
26-
const [circlePosition, setCirclePosition] = useState({ x: 70, y: 70 });
27-
const [circleInTheGoal, setCircleInTheGoal] = useState(false);
28-
return (
29-
<div>
30-
<h2>{circleInTheGoal ? 'GOAL!!' : 'Put the circle in the goal'}</h2>
31-
<div className="game-area">
32-
<Draggable position={circlePosition} onDrag={onCircleDrag}>
33-
<div
34-
className="circle"
35-
style={{
36-
width: 100,
37-
height: 100,
38-
borderRadius: 50,
39-
background: 'red',
40-
display: 'flex',
41-
justifyContent: 'center',
42-
alignItems: 'center',
43-
position: 'absolute',
44-
}}
45-
>
46-
<span>Circle</span>
47-
</div>
48-
</Draggable>
49-
<Draggable>
50-
<div
51-
className="obstacle"
52-
style={{
53-
width: 200,
54-
height: 200,
55-
background: 'blue',
56-
display: 'flex',
57-
justifyContent: 'center',
58-
alignItems: 'center',
59-
position: 'absolute',
60-
}}
61-
>
62-
<span>Obstacle</span>
63-
</div>
64-
</Draggable>
65-
<div
66-
className="goal"
67-
style={{
68-
...goal,
69-
border: '3px solid black',
70-
display: 'flex',
71-
justifyContent: 'center',
72-
alignItems: 'center',
73-
position: 'absolute',
74-
zIndex: -1,
75-
}}
76-
>
77-
<span>Goal</span>
78-
</div>
79-
</div>
80-
</div>
57+
}
58+
},
59+
}));
60+
61+
return (
62+
<div
63+
ref={drop}
64+
style={{
65+
position: "relative",
66+
width: "100vw",
67+
height: "100vh",
68+
border: "1px solid black",
69+
}}
70+
>
71+
<div
72+
id="goal" // Add id for the goal
73+
style={{
74+
position: "absolute",
75+
left: 300,
76+
top: 300,
77+
width: 100,
78+
height: 100,
79+
backgroundColor: "yellow",
80+
border: "2px dashed black",
81+
}}
82+
>
83+
Goal
84+
</div>
85+
</div>
86+
);
87+
};
88+
89+
const Game = () => {
90+
const [items, setItems] = useState([
91+
{ id: 1, type: ItemTypes.CIRCLE, x: 10, y: 10 }, // Red circle
92+
{ id: 2, type: ItemTypes.BOX, x: 10, y: -70 }, // Blue box starts entirely above the red circle
93+
]);
94+
const [goalMessage, setGoalMessage] = useState("Put the circle in the goal");
95+
96+
useEffect(() => {
97+
document.title = "Drag game"; // Set the page title
98+
}, []);
99+
100+
const handleDrop = (id, x, y) => {
101+
setItems((prevItems) =>
102+
prevItems.map((item) =>
103+
item.id === id ? { ...item, x, y } : item
104+
)
81105
);
82-
}
106+
};
107+
108+
const handleGoal = () => {
109+
setGoalMessage("GOAL!!!");
110+
};
111+
112+
return (
113+
<DndProvider backend={HTML5Backend}>
114+
<DropZone onDrop={handleDrop} onGoal={handleGoal} />
115+
{items.map((item) => (
116+
<DraggableItem
117+
key={item.id}
118+
id={item.id}
119+
type={item.type}
120+
x={item.x}
121+
y={item.y}
122+
/>
123+
))}
124+
<h2
125+
style={{
126+
position: "absolute",
127+
top: 20,
128+
left: "50%",
129+
transform: "translateX(-50%)",
130+
fontSize: "24px",
131+
fontWeight: "bold",
132+
color: goalMessage === "GOAL!!!" ? "green" : "black",
133+
}}
134+
>
135+
{goalMessage}
136+
</h2>
137+
<div
138+
id="invisible-element"
139+
style={{
140+
position: "absolute",
141+
top: 60, // Adjusted to be below the h2 element
142+
left: "50%",
143+
transform: "translateX(-50%)",
144+
width: "100px",
145+
height: "20px",
146+
visibility: "hidden", // Makes the element invisible
147+
}}
148+
>
149+
Invisible Element
150+
</div>
151+
</DndProvider>
152+
);
153+
};
154+
155+
export default Game;

0 commit comments

Comments
 (0)