Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save TheTridentGuy/4cfec5c8e177d585f35792413c92adf0 to your computer and use it in GitHub Desktop.

Select an option

Save TheTridentGuy/4cfec5c8e177d585f35792413c92adf0 to your computer and use it in GitHub Desktop.
import math
import random
from browser import document
SHIP_W = 30
SHIP_H = 40
ACCELERATION_INCREMENT = 0.1
ROTATION_INCREMENT = 3
BULLET_A = 15
BULLET_R = 5
ASTEROID_R = 10
arrow_up_down = False
arrow_down_down = False
arrow_left_down = False
arrow_right_down = False
space_down = False
collision_in_progress = False
def r(x, y, ox, oy, angle):
x = ox + math.cos(angle) * (x - ox) - math.sin(angle) * (y - oy)
y = oy + math.sin(angle) * (x - ox) + math.cos(angle) * (y - oy)
return x, y
class Ship():
def __init__(self, x, y):
self.x = x
self.y = y
self.a_x = 0
self.a_y = 0
self.r = 0
def move(self):
self.x += self.a_x
self.y += self.a_y
if self.x > canvas.width:
self.x = 0
elif self.x < 0:
self.x = canvas.width
if self.y > canvas.height:
self.y = 0
elif self.y < 0:
self.y = canvas.height
def draw(self):
ctx.translate(self.x, self.y)
ctx.rotate(math.radians(self.r+90))
ctx.fillStyle = "#000000"
ctx.beginPath()
ctx.moveTo(-SHIP_W/2, SHIP_H/2)
ctx.lineTo(SHIP_W/2, SHIP_H/2)
ctx.lineTo(0, -SHIP_H/2)
ctx.fill()
ctx.rotate(-math.radians(self.r+90))
ctx.translate(-self.x, -self.y)
class Bullet():
def __init__(self, x, y, r):
self.x = x
self.y = y
self.r = r
def move(self):
self.x += math.cos(math.radians(self.r))*BULLET_A
self.y += math.sin(math.radians(self.r))*BULLET_A
def draw(self):
ctx.fillStyle = "#000000"
ctx.beginPath()
ctx.arc(self.x, self.y, BULLET_R, 0, 360, False)
ctx.fill()
class Asteroid():
def __init__(self):
self.x = random.randint(0, canvas.width)
self.y = random.randint(0, canvas.height)
self.r = random.randint(0, 360)
self.a = random.random()*2
self.hp = random.randint(1, 3)
def move(self):
self.x += math.cos(math.radians(self.r))*self.a
self.y += math.sin(math.radians(self.r))*self.a
if self.x > canvas.width:
self.x = 0
elif self.x < 0:
self.x = canvas.width
if self.y > canvas.height:
self.y = 0
elif self.y < 0:
self.y = canvas.height
def damage(self):
self.hp -= 1
def draw(self):
ctx.fillStyle = "#000000"
ctx.beginPath()
ctx.arc(self.x, self.y, abs(ASTEROID_R*self.hp), 0, 360, False)
ctx.fill()
class Particle():
def __init__(self, x, y, color):
self.x = x
self.y = y
self.r = random.randint(0, 360)
self.life = random.randint(3,7)
self.color = color
def move(self):
self.x += math.cos(math.radians(self.r))*BULLET_A
self.y += math.sin(math.radians(self.r))*BULLET_A
def draw(self):
self.life -= 1
ctx.fillStyle = self.color
ctx.beginPath()
ctx.arc(self.x, self.y, random.randint(2,5), 0, 360, False)
ctx.fill()
def draw_frame():
global score, hp, collision_in_progress
clean()
if hp <= 0:
draw_end_frame()
return
ctx.clearRect(0, 0, canvas.width, canvas.height)
if arrow_up_down:
ship.a_x += math.cos(math.radians(ship.r))*ACCELERATION_INCREMENT
ship.a_y += math.sin(math.radians(ship.r))*ACCELERATION_INCREMENT
if arrow_down_down:
ship.a_x -= math.cos(math.radians(ship.r))*ACCELERATION_INCREMENT
ship.a_y -= math.sin(math.radians(ship.r))*ACCELERATION_INCREMENT
if arrow_left_down:
ship.r -= ROTATION_INCREMENT
if arrow_right_down:
ship.r += ROTATION_INCREMENT
if space_down:
bullets.append(Bullet(ship.x, ship.y, ship.r))
for particle in particles:
particle.move()
particle.draw()
for bullet in bullets:
for asteroid in asteroids:
if abs(bullet.x - asteroid.x) < ASTEROID_R*asteroid.hp and abs(bullet.y - asteroid.y) < ASTEROID_R*asteroid.hp:
score += 1
asteroid.damage()
particles.extend([Particle(asteroid.x, asteroid.y, "orange") for _ in range(8)])
particles.extend([Particle(asteroid.x, asteroid.y, "yellow") for _ in range(6)])
bullet.move()
bullet.draw()
had_collision = False
for asteroid in asteroids:
if abs(ship.x - asteroid.x) < ASTEROID_R*asteroid.hp and abs(ship.y - asteroid.y) < ASTEROID_R*asteroid.hp:
had_collision = True
if not collision_in_progress:
hp -= 1
collision_in_progress = True
particles.extend([Particle(ship.x, ship.y, "blue") for _ in range(15)])
asteroid.move()
asteroid.draw()
if not had_collision:
collision_in_progress = False
ctx.font = "30px monospace"
if score < 20:
ctx.fillStyle = "#000000"
elif score < 40:
ctx.fillStyle = "orange"
elif score < 60:
ctx.fillStyle = "red"
elif score < 150:
ctx.fillStyle = "blue"
particles.extend([Particle(30, 25, "blue") for _ in range(3)])
else:
color = random.choice(["#00ff00", "#009f00", "#00fe00", "#00fd00"])
particles.extend([Particle(30, 25, color) for _ in range(5)])
ctx.fillStyle = color
ctx.fillText(score, 10, 40)
ship.move()
ship.draw()
for i in range(hp):
draw_heart(10+20 *i, canvas.height-25)
def keydown(event):
global arrow_up_down, arrow_down_down, arrow_left_down, arrow_right_down, space_down
if event.key in ["ArrowUp", "w"]:
arrow_up_down = True
elif event.key in ["ArrowDown", "s"]:
arrow_down_down = True
elif event.key in ["ArrowLeft", "a"]:
arrow_left_down = True
elif event.key in ["ArrowRight", "d"]:
arrow_right_down = True
elif event.key == " ":
space_down = True
def draw_end_frame():
for particle in particles:
particle.move()
particle.draw()
ctx.fillStyle = "#000000"
ctx.font = "30px monospace"
ctx.fillText("Game Over", canvas.width/2-80, canvas.height/2-10)
ctx.fillText(score, canvas.width/2-10, canvas.height/2+20)
def keyup(event):
global arrow_up_down, arrow_down_down, arrow_left_down, arrow_right_down, space_down
if event.key in ["ArrowUp", "w"]:
arrow_up_down = False
elif event.key in ["ArrowDown", "s"]:
arrow_down_down = False
elif event.key in ["ArrowLeft", "a"]:
arrow_left_down = False
elif event.key in ["ArrowRight", "d"]:
arrow_right_down = False
elif event.key == " ":
space_down = False
def clean():
global bullets, asteroids, particles
good_bullets = []
for bullet in bullets:
if 0 <= bullet.x <= canvas.width and 0 <= bullet.y <= canvas.height:
good_bullets.append(bullet)
bullets = good_bullets
live_asteroids = []
for asteroid in asteroids:
if asteroid.hp <= 0:
live_asteroids.append(Asteroid())
else:
live_asteroids.append(asteroid)
asteroids = live_asteroids
live_particles = []
for particle in particles:
if particle.life > 0:
live_particles.append(particle)
particles = live_particles
def draw_heart(x, y, scale=6):
ctx.fillStyle = "red"
ctx.fillRect(x, y, scale, 2*scale)
ctx.fillRect(x+scale, y+scale, scale, 2*scale)
ctx.fillRect(x+2*scale, y, scale, 2*scale)
document.addEventListener("keydown", keydown)
document.addEventListener("keyup", keyup)
ship = Ship(canvas.width/2, canvas.height/2)
bullets = []
asteroids = [Asteroid() for _ in range(5)]
score = 0
particles = []
hp = 6
print("Click inside the canvas to focus it.")
print("WASD to move, SPACE to fire.")
print("This game has infinite endings, because you can end with any score, and every frame is a scene.")
interval = timer.set_interval(draw_frame, 10)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment