Rope snake game

master
mian 2 months ago
parent ff23d95d0c
commit d2438867df
  1. 26
      rope_snake/index.html
  2. 94
      rope_snake/intersect.js
  3. 59
      rope_snake/segment.js
  4. 99
      rope_snake/sketch.js

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>p5.js example</title>
<style>
body {
padding: 0;
margin: 0;
}
</style>
<script src="../p5.js"></script>
<!-- <script src="../addons/p5.sound.js"></script> -->
<script src="intersect.js"></script>
<script src="segment.js"></script>
<script src="sketch.js"></script>
</head>
<body>
<main>
</main>
</body>
</html>

@ -0,0 +1,94 @@
// Javascript program to check if two given line segments intersect
// Given three collinear points p, q, r, the function checks if
// point q lies on line segment 'pr'
function onSegment(p, q, r)
{
if (q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) &&
q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y))
return true;
return false;
}
// To find orientation of ordered triplet (p, q, r).
// The function returns following values
// 0 --> p, q and r are collinear
// 1 --> Clockwise
// 2 --> Counterclockwise
function orientation(p, q, r)
{
// See https://www.geeksforgeeks.org/orientation-3-ordered-points/
// for details of below formula.
let val = (q.y - p.y) * (r.x - q.x) -
(q.x - p.x) * (r.y - q.y);
if (val == 0) return 0; // collinear
return (val > 0)? 1: 2; // clock or counterclock wise
}
// The main function that returns true if line segment 'p1q1'
// and 'p2q2' intersect.
function doIntersect(p1, q1, p2, q2)
{
// Find the four orientations needed for general and
// special cases
let o1 = orientation(p1, q1, p2);
let o2 = orientation(p1, q1, q2);
let o3 = orientation(p2, q2, p1);
let o4 = orientation(p2, q2, q1);
// General case
if (o1 != o2 && o3 != o4)
return true;
// Special Cases
// p1, q1 and p2 are collinear and p2 lies on segment p1q1
if (o1 == 0 && onSegment(p1, p2, q1)) return true;
// p1, q1 and q2 are collinear and q2 lies on segment p1q1
if (o2 == 0 && onSegment(p1, q2, q1)) return true;
// p2, q2 and p1 are collinear and p1 lies on segment p2q2
if (o3 == 0 && onSegment(p2, p1, q2)) return true;
// p2, q2 and q1 are collinear and q1 lies on segment p2q2
if (o4 == 0 && onSegment(p2, q1, q2)) return true;
return false; // Doesn't fall in any of the above cases
}
function test_intersect(){
// Driver code
let p1 = new Vector(1, 1);
let q1 = new Vector(10, 1);
let p2 = new Vector(1, 2);
let q2 = new Vector(10, 2);
if(doIntersect(p1, q1, p2, q2))
console.log("Yes<br>");
else
console.log("No<br>");
p1 = new Vector(10, 1); q1 = new Vector(0, 10);
p2 = new Vector(0, 0); q2 = new Vector(10, 10);
if(doIntersect(p1, q1, p2, q2))
console.log("Yes<br>");
else
console.log("No<br>");
p1 = new Vector(-5, -5); q1 = new Vector(0, 0);
p2 = new Vector(1, 1); q2 = new Vector(10, 10);;
if(doIntersect(p1, q1, p2, q2))
console.log("Yes<br>");
else
console.log("No<br>");
}
// This code is contributed by avanitrachhadiya2155

@ -0,0 +1,59 @@
const Vector = p5.Vector;
function Segment(startx, starty, len, heading){
this.start = new Vector(startx, starty);
this.len = len;
this.reference = 0;
this.heading = heading;
this.child = null;
this.parent = null;
};
Segment.prototype.end = function(){
angle = this.heading + this.reference;
let x = this.len * cos(angle) + this.start.x;
let y = this.len * sin(angle) + this.start.y;
return new Vector(x,y);
};
Segment.prototype.update = function(){
if(!this.parent) return;
this.parent.heading = Vector.sub(this.start, this.parent.start).heading();
this.parent.start.add(Vector.sub(this.start, this.parent.end()));
this.parent.update();
};
Segment.prototype.setHeading = function(angle){
this.heading = angle;
this.update();
};
Segment.prototype.draw = function(){
push();
stroke(255);
strokeWeight(5);
line(
this.start.x,
this.start.y,
this.end().x,
this.end().y);
pop();
};
Segment.prototype.expand_parent = function(stx, sty, len, heading){
let next = new Segment(stx, sty, len, heading);
next.child = this;
this.parent = next;
return next;
};
Segment.prototype.eats_parents = function(){
let start = this.start;
let end = this.end();
for(let theSeg = this.parent.parent; theSeg != null; theSeg = theSeg.parent)
if(doIntersect(start, end, theSeg.start, theSeg.end()))
return true;
return false;
};

@ -0,0 +1,99 @@
const START_SEGMENTS = 10;
const SEG_LEN = 10;
const SPEED = 4;
const WIDTH = 300;
const HEIGHT = 300;
const APPLE_SIZE = 20;
const APPLE_R = APPLE_SIZE/2;
const SPACE_BAR = 32;
let head;
let tail;
let apple;
let turn = 0;
let speedup = 0;
const isOutside = (aVec) => (
aVec.x > WIDTH ||
aVec.x < 0 ||
aVec.y > HEIGHT ||
aVec.y < 0);
function setup() {
// put setup code here
apple = new Vector(random(APPLE_R,WIDTH-APPLE_R),
random(APPLE_R,HEIGHT-APPLE_R));
tail = new Segment(WIDTH/2, 0, 10, HALF_PI);
head = tail
for(let i = 0; i < START_SEGMENTS; i++){
let pos = head.end();
head.child = new Segment(pos.x, pos.y, 10, HALF_PI);
head.child.parent = head;
head = head.child;
}
createCanvas(300,300);
frameRate(15);
}
function draw() {
// put drawing code here
background(0);
for(let current = tail; current !== null; current= current.child){
current.draw();
}
fill(0, 255, 0);
noStroke();
circle(apple.x, apple.y, APPLE_SIZE);
// update
head.heading += turn * PI/18;
head.start.add(p5.Vector.fromAngle(head.heading, SPEED*(1+speedup)));
head.update();
head_end = head.end();
if(Vector.sub(head_end, apple).mag() < APPLE_SIZE){
apple = new Vector(random(APPLE_R,WIDTH-APPLE_R),
random(APPLE_R,HEIGHT-APPLE_R));
for(let i=1; i<=3; i++){
let end = tail.end();
let heading = tail.heading;
tail = tail.expand_parent(end.x, end.y, SEG_LEN, heading+ PI);
}
}
// Game over
if(isOutside(head_end) || head.eats_parents())
{
background(128);
textSize(HEIGHT/10);
textAlign(CENTER);
text("Game Over! Refresh page to restart.",
0.1*WIDTH, 0.1*HEIGHT,
0.8*WIDTH, 0.8*HEIGHT)
noLoop();
};
}
function keyPressed(){
switch(keyCode){
case LEFT_ARROW:
turn = -1;
break;
case RIGHT_ARROW:
turn = +1;
break;
case SPACE_BAR:
speedup = 1;
break;
}
}
function keyReleased(){
switch(keyCode){
case LEFT_ARROW:
case RIGHT_ARROW:
turn = 0;
break;
case SPACE_BAR:
speedup = 0;
break;
}
}
Loading…
Cancel
Save