Code edit (2 edits merged)
Please save this source code
User prompt
In ScoreMultipliers add a score label text string. This should be white with the font Impact.
Code edit (10 edits merged)
Please save this source code
User prompt
Use impact for the score label
User prompt
Add a score label to the top center of the screen. The score label should be centered and have a black outline and white font
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
when circles and barriers intersect, move the circle back, such that it just touches the barrier and no longer intersects
Code edit (1 edits merged)
Please save this source code
User prompt
Move the ball outside the barrier so they no longer intersects, when they intersect
Code edit (7 edits merged)
Please save this source code
User prompt
When intersecting a barrier, the new speed should be based on ball to ball intersection like billiard balls. With the barrier being static and the bubbles being standard billiard balls
User prompt
Bubbles should bounce on barriers, using circle to circle intersections and billiard ball like physics
Code edit (1 edits merged)
Please save this source code
User prompt
When intersection a barrier with a bubble. Move the bubble out of the barrier such that they no longer intersects
User prompt
If a ball intersects a barrier, it should be rejected out of the barrier
Code edit (11 edits merged)
Please save this source code
User prompt
The bubbles seems to intersect with the barriers more than once, please update the code such that it only triggers if the bubble is moving towards each specific barrier
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
Code edit (6 edits merged)
Please save this source code
User prompt
Bubbles should intersect barriers, and bounce based on circle to line intersection. With each barrier being considered four lines and each bubble being a circle. The balls should bounce of the barriers similar to how the logic would be implemented in billiard or eight ball pool. Please consider that both bubbles and barriers have their anchor set at .5,.5
User prompt
Bubbles should intersect barriers, and bounce based on circle to line intersection. With each barrier being considered four lines and each bubble being a circle. The balls should bounce of the barriers similar to how the logic would be implemented in billiard or eight ball pool. Please consider that both bubbles and barriers have their anchor set at .5,.5
Code edit (1 edits merged)
Please save this source code
User prompt
Bubbles should intersect barriers, and bounce based on circle to line intersection. With each barrier being considered four lines. The balls should bounce of the barriers similar to how the logic would be implemented in billiard or eight ball pool.
/**** * Classes ****/ var Barrier = Container.expand(function () { var self = Container.call(this); var barrierGraphics = self.attachAsset('barrier', { anchorX: .5, anchorY: .5 }); }); var Bubble = Container.expand(function (max_types) { var self = Container.call(this); var colors = [0xff0000, 0x00ff00, 0x0000ff, 0xff00ff, 0xffff00, 0x00ffff, 0xffffff]; var bubbleGraphics = self.attachAsset('bubble', { anchorX: 0.5, anchorY: 0.5 }); var state = 0; var targetX = 0; var targetY = 0; var isAttached = true; var speedX = 0; var speedY = 0; self.setPos = function (x, y) { self.x = targetX = x; self.y = targetY = y; }; max_types = max_types || 3; self.type = Math.floor(Math.random() * max_types); bubbleGraphics.tint = colors[self.type]; self.detatch = function () { game.addChild(self); self.y += grid.y; isAttached = false; speedX = Math.random() * 40 - 20; speedY = -Math.random() * 30; self.down = undefined; }; self.update = function () { if (!isAttached) { self.x += speedX; self.y += speedY; speedY += 1.5; if (self.x < self.width / 2 && speedX < 0 || self.x > game.width - self.width / 2 && speedX > 0) { speedX = -speedX; } // Check for intersection with each barrier for (var i = 0; i < barriers.length; i++) { var barrier = barriers[i]; var lines = [{ x1: barrier.x - barrier.width / 2, y1: barrier.y - barrier.height / 2, x2: barrier.x + barrier.width / 2, y2: barrier.y - barrier.height / 2 }, { x1: barrier.x + barrier.width / 2, y1: barrier.y - barrier.height / 2, x2: barrier.x + barrier.width / 2, y2: barrier.y + barrier.height / 2 }, { x1: barrier.x + barrier.width / 2, y1: barrier.y + barrier.height / 2, x2: barrier.x - barrier.width / 2, y2: barrier.y + barrier.height / 2 }, { x1: barrier.x - barrier.width / 2, y1: barrier.y + barrier.height / 2, x2: barrier.x - barrier.width / 2, y2: barrier.y - barrier.height / 2 }]; for (var j = 0; j < lines.length; j++) { var line = lines[j]; var intersects = circleLineSegmentIntersection({ x: self.x, y: self.y, radius: self.width / 2 }, line); if (intersects) { isAttached = true; // Bounce off the barrier var normal = { x: line.y2 - line.y1, y: line.x1 - line.x2 }; var magnitude = Math.sqrt(normal.x * normal.x + normal.y * normal.y); normal.x /= magnitude; normal.y /= magnitude; var dot = speedX * normal.x + speedY * normal.y; // Only bounce if the bubble is moving towards the barrier if (dot < 0) { speedX -= 2 * dot * normal.x; speedY -= 2 * dot * normal.y; // Move the bubble out of the barrier while (circleLineSegmentIntersection({ x: self.x, y: self.y, radius: self.width / 2 }, line)) { self.x += normal.x; self.y += normal.y; } break; } } } } } }; }); var Grid = Container.expand(function () { var self = Container.call(this); var rows = []; self.container = self.addChild(new Container()); var rowCount = 0; function insertRow() { var row = []; var rowWidth = rowCount % 2 == 0 ? 13 : 12; for (var a = 0; a < rowWidth; a++) { var bubble = new Bubble(); bubble.setPos((2048 - bubble.width * rowWidth) / 2 + bubble.width * a + bubble.width / 2, -rowCount * (1.7320508076 * bubble.height) / 2); self.container.addChild(bubble); row.push(bubble); bubble.down = function () { var bubbles = self.getConnectedBubbles(this); self.removeBubbles(bubbles); var disconnected = self.getDetachedBubbles(); self.removeBubbles(disconnected); }; } rows.push(row); rowCount++; } //Method that removes an array of bubbles from the rows array. self.removeBubbles = function (bubbles) { for (var i = 0; i < bubbles.length; i++) { var bubble = bubbles[i]; var bubbleIndex = this.findBubbleIndex(bubble); if (bubbleIndex) { rows[bubbleIndex.row][bubbleIndex.col] = null; bubble.detatch(); } } }; self.getConnectedBubbles = function (bubble, ignoreType) { var connectedBubbles = []; var queue = [bubble]; var visited = []; while (queue.length > 0) { var currentBubble = queue.shift(); if (visited.indexOf(currentBubble) === -1) { visited.push(currentBubble); connectedBubbles.push(currentBubble); var neighbors = self.getNeighbors(currentBubble); for (var i = 0; i < neighbors.length; i++) { var neighbor = neighbors[i]; if (neighbor && (neighbor.type === bubble.type || ignoreType)) { queue.push(neighbor); } } } } return connectedBubbles; }; //Get a list of bubbles that are not connected to the top row, or to a chain of bubbles connected to the top row. self.getDetachedBubbles = function () { var detachedBubbles = []; var connectedToTop = []; // Mark all bubbles connected to the bottom row var lastRowIndex = rows.length - 1; for (var i = 0; i < rows[lastRowIndex].length; i++) { if (rows[lastRowIndex][i] !== null) { var bottomConnected = self.getConnectedBubbles(rows[lastRowIndex][i], true); connectedToTop = connectedToTop.concat(bottomConnected); } } // Mark all bubbles as visited or not var visited = connectedToTop.filter(function (bubble) { return bubble != null; }); // Find all bubbles that are not visited and not connected to the top for (var row = 0; row < rows.length - 1; row++) { for (var col = 0; col < rows[row].length; col++) { var bubble = rows[row][col]; if (bubble !== null && visited.indexOf(bubble) == -1) { detachedBubbles.push(bubble); } } } return detachedBubbles; }; self.getNeighbors = function (bubble) { var neighbors = []; var bubbleIndex = this.findBubbleIndex(bubble); var directions = [[-1, 0], [1, 0], // left and right [0, -1], [0, 1], // above and below [-1, -1], [1, -1] // diagonals for even rows ]; if (bubbleIndex.row % 2 === 1) { // Adjust diagonals for odd rows directions[4] = [-1, 1]; directions[5] = [1, 1]; } for (var i = 0; i < directions.length; i++) { var dir = directions[i]; var newRow = bubbleIndex.row + dir[0]; var newCol = bubbleIndex.col + dir[1]; if (newRow >= 0 && newRow < rows.length && newCol >= 0 && newCol < rows[newRow].length) { neighbors.push(rows[newRow][newCol]); } } return neighbors; }; self.findBubbleIndex = function (bubble) { for (var row = 0; row < rows.length; row++) { var col = rows[row].indexOf(bubble); if (col !== -1) { return { row: row, col: col }; } } return null; }; insertRow(); insertRow(); insertRow(); insertRow(); insertRow(); insertRow(); insertRow(); insertRow(); insertRow(); }); var HintBubble = Container.expand(function () { var self = Container.call(this); }); var Launcher = Container.expand(function () { var self = Container.call(this); }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x010c42 }); /**** * Game Code ****/ // Method to calculate the intersection between a circle and a line //Game size 2048x2732 function circleLineSegmentIntersection(circle, lineSegment) { var cx = circle.x, cy = circle.y, radius = circle.radius; var x1 = lineSegment.x1, y1 = lineSegment.y1, x2 = lineSegment.x2, y2 = lineSegment.y2; // Calculate distances var dx = x2 - x1; var dy = y2 - y1; var a = dx * dx + dy * dy; var b = 2 * (dx * (x1 - cx) + dy * (y1 - cy)); var c = (x1 - cx) * (x1 - cx) + (y1 - cy) * (y1 - cy) - radius * radius; var det = b * b - 4 * a * c; if (a <= 0.0000001 || det < 0) { // No real solutions, no intersection return false; } else if (det == 0) { // One solution, tangent line var t = -b / (2 * a); return t >= 0 && t <= 1; } else { // Two solutions, check if either are on the segment var t1 = (-b + Math.sqrt(det)) / (2 * a); var t2 = (-b - Math.sqrt(det)) / (2 * a); return t1 >= 0 && t1 <= 1 || t2 >= 0 && t2 <= 1; } } var grid = game.addChild(new Grid()); grid.y = 1300; var barriers = []; for (var a = 0; a < 4; a++) { var barrier = game.addChild(new Barrier()); barrier.y = 2732 - 500; barrier.x = 2048 / 5 * a + 2048 / 5; barriers.push(barrier); } /*var testBubble = game.addChild(new Bubble()); game.move = function (x, y) { var barrier = barriers[barriers.length - 1]; var lines = [{ x1: barrier.x - barrier.width / 2, y1: barrier.y - barrier.height / 2, x2: barrier.x + barrier.width / 2, y2: barrier.y - barrier.height / 2 }, { x1: barrier.x + barrier.width / 2, y1: barrier.y - barrier.height / 2, x2: barrier.x + barrier.width / 2, y2: barrier.y + barrier.height / 2 }, { x1: barrier.x + barrier.width / 2, y1: barrier.y + barrier.height / 2, x2: barrier.x - barrier.width / 2, y2: barrier.y + barrier.height / 2 }, { x1: barrier.x - barrier.width / 2, y1: barrier.y + barrier.height / 2, x2: barrier.x - barrier.width / 2, y2: barrier.y - barrier.height / 2 }]; testBubble.x = x; testBubble.y = y; console.log(circleLineSegmentIntersection({ x: x, y: y, radius: 150 / 2 }, lines[3])); };*/
===================================================================
--- original.js
+++ change.js
@@ -75,30 +75,32 @@
y: self.y,
radius: self.width / 2
}, line);
if (intersects) {
- // Calculate the direction of the bubble
- var direction = {
- x: self.x - (self.x - speedX),
- y: self.y - (self.y - speedY)
- };
- // Calculate the normal of the barrier
+ isAttached = true;
+ // Bounce off the barrier
var normal = {
x: line.y2 - line.y1,
y: line.x1 - line.x2
};
- // Calculate the dot product of the direction and the normal
- var dot = direction.x * normal.x + direction.y * normal.y;
- // If the dot product is less than 0, the bubble is moving towards the barrier
+ var magnitude = Math.sqrt(normal.x * normal.x + normal.y * normal.y);
+ normal.x /= magnitude;
+ normal.y /= magnitude;
+ var dot = speedX * normal.x + speedY * normal.y;
+ // Only bounce if the bubble is moving towards the barrier
if (dot < 0) {
- // Reflect the bubble off the barrier
- var reflection = {
- x: direction.x - 2 * dot * normal.x,
- y: direction.y - 2 * dot * normal.y
- };
- // Update the speed of the bubble to be the reflection
- speedX = reflection.x;
- speedY = reflection.y;
+ speedX -= 2 * dot * normal.x;
+ speedY -= 2 * dot * normal.y;
+ // Move the bubble out of the barrier
+ while (circleLineSegmentIntersection({
+ x: self.x,
+ y: self.y,
+ radius: self.width / 2
+ }, line)) {
+ self.x += normal.x;
+ self.y += normal.y;
+ }
+ break;
}
}
}
}
@@ -248,10 +250,10 @@
/****
* Game Code
****/
-//Game size 2048x2732
// Method to calculate the intersection between a circle and a line
+//Game size 2048x2732
function circleLineSegmentIntersection(circle, lineSegment) {
var cx = circle.x,
cy = circle.y,
radius = circle.radius;
Circular white gradient circle on black background. Gradient from white on the center to black on the outer edge all around.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Soft straight Long red paint on black background. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Fire ball. Bubble shooter game. Thin black outline.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
green notification bubble. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.