first commit :D
BIN
src/assets/cow.png
Normal file
|
After Width: | Height: | Size: 666 B |
BIN
src/assets/grass.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
src/assets/player.jpg
Normal file
|
After Width: | Height: | Size: 710 B |
BIN
src/assets/player.png
Normal file
|
After Width: | Height: | Size: 470 B |
BIN
src/assets/player_still.png
Normal file
|
After Width: | Height: | Size: 460 B |
BIN
src/assets/player_still_eyesclosed.png
Normal file
|
After Width: | Height: | Size: 454 B |
BIN
src/assets/vodkaguy.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
src/assets/water.png
Normal file
|
After Width: | Height: | Size: 515 B |
12
src/index.html
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Hello World</title>
|
||||||
|
<link rel="stylesheet" href="main.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script src="lib/pixi/pixi.v5.3.10.min.js"></script>
|
||||||
|
<script src="main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
9
src/lib/pixi/pixi.v5.3.10.min.js
vendored
Normal file
8
src/main.css
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
html { background-color: #206272; }
|
||||||
|
body { margin: 0; }
|
||||||
|
canvas {
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, 0);
|
||||||
|
}
|
||||||
473
src/main.js
Normal file
|
|
@ -0,0 +1,473 @@
|
||||||
|
const WIDTH = 800
|
||||||
|
const HEIGHT = 600
|
||||||
|
|
||||||
|
const SPEED = 5
|
||||||
|
const TARGET_AREA_WIDTH = 350
|
||||||
|
|
||||||
|
const IDLE = 4000
|
||||||
|
|
||||||
|
const app = new PIXI.Application({
|
||||||
|
width: WIDTH,
|
||||||
|
height: HEIGHT,
|
||||||
|
backgroundColor: 0x1099bb,
|
||||||
|
resolution: window.devicePixelRatio || 1,
|
||||||
|
});
|
||||||
|
document.body.appendChild(app.view);
|
||||||
|
|
||||||
|
var container = new PIXI.Container();
|
||||||
|
var hud = new PIXI.Container();
|
||||||
|
var endC = new PIXI.Container();
|
||||||
|
endC.visible = false
|
||||||
|
app.stage.addChild(container);
|
||||||
|
app.stage.addChild(hud);
|
||||||
|
app.stage.addChild(endC);
|
||||||
|
|
||||||
|
const resources = PIXI.loader.resources
|
||||||
|
|
||||||
|
var player, state, objects, maxX, lastKey, PTS_WATER, PTS_COWS, END_TXT
|
||||||
|
|
||||||
|
PIXI.loader
|
||||||
|
.add("assets/player.png")
|
||||||
|
.add("assets/player_still.png")
|
||||||
|
.add("assets/player_still_eyesclosed.png")
|
||||||
|
.add("assets/cow.png")
|
||||||
|
.add("assets/water.png")
|
||||||
|
.add("assets/vodkaguy.png")
|
||||||
|
.add("assets/grass.png")
|
||||||
|
.load(setup);
|
||||||
|
|
||||||
|
function setup () {
|
||||||
|
const playerTexture = resources['assets/player_still.png'].texture
|
||||||
|
const cowTexture = resources['assets/cow.png'].texture
|
||||||
|
const waterTexture = resources['assets/water.png'].texture
|
||||||
|
|
||||||
|
const vodkaguyTexture = resources['assets/vodkaguy.png'].texture
|
||||||
|
const grassTexture = resources['assets/grass.png'].texture
|
||||||
|
|
||||||
|
PTS_WATER = new PIXI.Text('0/20', {fontFamily : 'Arial', fontSize: 24, fill : 0xff1010, align : 'center'});
|
||||||
|
PTS_COWS = new PIXI.Text('0/20', {fontFamily : 'Arial', fontSize: 24, fill : 0xff1010, align : 'center'});
|
||||||
|
END_TXT = new PIXI.Text('YOU WIN!!!', {fontFamily : 'Arial', fontSize: 24, fill : 0xffff00, align : 'center'});
|
||||||
|
END_TXT.visible = false
|
||||||
|
|
||||||
|
|
||||||
|
PTS_WATER.y = 20
|
||||||
|
PTS_WATER.x = 20
|
||||||
|
PTS_COWS.y = 50
|
||||||
|
PTS_COWS.x = 20
|
||||||
|
|
||||||
|
hud.addChild(PTS_WATER)
|
||||||
|
hud.addChild(PTS_COWS)
|
||||||
|
|
||||||
|
const vodkaguy = new PIXI.Sprite(vodkaguyTexture)
|
||||||
|
container.addChild(vodkaguy)
|
||||||
|
vodkaguy.x = 0
|
||||||
|
vodkaguy.y = 0
|
||||||
|
|
||||||
|
const grass = new PIXI.Sprite(grassTexture)
|
||||||
|
container.addChild(grass)
|
||||||
|
grass.x = 0
|
||||||
|
grass.y = 0
|
||||||
|
|
||||||
|
player = new PIXI.Sprite(playerTexture);
|
||||||
|
|
||||||
|
player.anchor.x = 0.5
|
||||||
|
player.anchor.y = 0.5
|
||||||
|
|
||||||
|
player.x = TARGET_AREA_WIDTH + 50
|
||||||
|
player.y = TARGET_AREA_WIDTH + 50
|
||||||
|
player.vx = 0
|
||||||
|
player.vy = 0
|
||||||
|
|
||||||
|
player.taps = []
|
||||||
|
|
||||||
|
let left = keyboard(37),
|
||||||
|
up = keyboard(38),
|
||||||
|
right = keyboard(39),
|
||||||
|
down = keyboard(40),
|
||||||
|
space = keyboard(32);
|
||||||
|
|
||||||
|
left.press = () => {
|
||||||
|
player.vx = -SPEED
|
||||||
|
lastKey = new Date().getTime()
|
||||||
|
}
|
||||||
|
left.release = () => {
|
||||||
|
if (!right.isDown) {
|
||||||
|
player.vx = 0
|
||||||
|
}
|
||||||
|
lastKey = new Date().getTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
right.press = () => {
|
||||||
|
player.vx = SPEED
|
||||||
|
lastKey = new Date().getTime()
|
||||||
|
}
|
||||||
|
right.release = () => {
|
||||||
|
if (!left.isDown) {
|
||||||
|
player.vx = 0
|
||||||
|
}
|
||||||
|
lastKey = new Date().getTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
up.press = () => {
|
||||||
|
player.vy = -SPEED
|
||||||
|
lastKey = new Date().getTime()
|
||||||
|
}
|
||||||
|
up.release = () => {
|
||||||
|
if (!down.isDown) {
|
||||||
|
player.vy = 0
|
||||||
|
}
|
||||||
|
lastKey = new Date().getTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
down.press = () => {
|
||||||
|
player.vy = SPEED
|
||||||
|
lastKey = new Date().getTime()
|
||||||
|
}
|
||||||
|
down.release = () => {
|
||||||
|
if (!up.isDown) {
|
||||||
|
player.vy = 0
|
||||||
|
}
|
||||||
|
lastKey = new Date().getTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
space.release = () => {
|
||||||
|
player.taps.push(true)
|
||||||
|
lastKey = new Date().getTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
objects = []
|
||||||
|
|
||||||
|
maxX = 0
|
||||||
|
const cows = 20
|
||||||
|
const waters = 20
|
||||||
|
for (let i = 0; i < cows; i++) {
|
||||||
|
const cow = new PIXI.Sprite(cowTexture)
|
||||||
|
cow.anchor.x = 0.5
|
||||||
|
cow.anchor.y = 0.5
|
||||||
|
|
||||||
|
const offset = 30
|
||||||
|
cow.x = player.x + player.width + i * (cow.width + offset)
|
||||||
|
cow.y = Math.floor(Math.random() * (HEIGHT - cow.height) + cow.height/2)
|
||||||
|
|
||||||
|
cow.vx = 0
|
||||||
|
cow.vy = 0
|
||||||
|
cow.vrot = 0
|
||||||
|
cow.ticks = 0
|
||||||
|
cow.type = 'cow'
|
||||||
|
container.addChild(cow)
|
||||||
|
|
||||||
|
objects.push(cow)
|
||||||
|
|
||||||
|
maxX = Math.max(maxX, cow.x + cow.width)
|
||||||
|
}
|
||||||
|
|
||||||
|
grass.x = maxX
|
||||||
|
|
||||||
|
for (let i = 0; i < waters; i++) {
|
||||||
|
const water = new PIXI.Sprite(waterTexture)
|
||||||
|
water.anchor.x = 0.5
|
||||||
|
water.anchor.y = 0.5
|
||||||
|
|
||||||
|
const offset = 30
|
||||||
|
water.x = player.x + player.width + i * (water.width + offset)
|
||||||
|
water.y = Math.floor(Math.random() * (HEIGHT - water.height) + water.height/2)
|
||||||
|
|
||||||
|
water.vx = 0
|
||||||
|
water.vy = 0
|
||||||
|
water.vrot = 0
|
||||||
|
water.ticks = 0
|
||||||
|
water.type = 'water'
|
||||||
|
container.addChild(water)
|
||||||
|
|
||||||
|
objects.push(water)
|
||||||
|
|
||||||
|
maxX = Math.max(maxX, water.x + water.width)
|
||||||
|
}
|
||||||
|
|
||||||
|
container.addChild(player)
|
||||||
|
|
||||||
|
endC.addChild(END_TXT)
|
||||||
|
|
||||||
|
state = play;
|
||||||
|
|
||||||
|
//Start the game loop
|
||||||
|
app.ticker.add(delta => gameLoop(delta));
|
||||||
|
}
|
||||||
|
|
||||||
|
function gameLoop(delta){
|
||||||
|
state(delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function end(delta) {
|
||||||
|
hud.visible = false
|
||||||
|
endC.visible = true
|
||||||
|
if (player.scale.x < 250) {
|
||||||
|
player.scale.x += 5
|
||||||
|
player.scale.y += 5
|
||||||
|
} else {
|
||||||
|
END_TXT.anchor.x = .5
|
||||||
|
END_TXT.anchor.y = .5
|
||||||
|
END_TXT.x = player.x
|
||||||
|
END_TXT.y = player.y
|
||||||
|
END_TXT.visible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var blinkStart
|
||||||
|
const BLINK_DUR = 250
|
||||||
|
function play(delta) {
|
||||||
|
player.x += player.vx
|
||||||
|
player.y += player.vy
|
||||||
|
|
||||||
|
if (player.vx < 0) {
|
||||||
|
player.angle = 0
|
||||||
|
player.scale.set(-1, 1)
|
||||||
|
}
|
||||||
|
if (player.vy > 0) {
|
||||||
|
player.angle = 90
|
||||||
|
player.scale.set(1, 1)
|
||||||
|
}
|
||||||
|
if (player.vy < 0) {
|
||||||
|
player.angle = 270
|
||||||
|
player.scale.set(1, 1)
|
||||||
|
}
|
||||||
|
if (player.vx > 0) {
|
||||||
|
player.angle = 0
|
||||||
|
player.scale.set(1, 1)
|
||||||
|
}
|
||||||
|
if (player.vy === 0 && player.vx === 0) {
|
||||||
|
player.texture = resources['assets/player_still.png'].texture
|
||||||
|
} else {
|
||||||
|
player.texture = resources['assets/player.png'].texture
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let now = new Date().getTime()
|
||||||
|
if (now - lastKey > IDLE) {
|
||||||
|
if (blinkStart) {
|
||||||
|
// is blinking
|
||||||
|
if (now - blinkStart > BLINK_DUR) {
|
||||||
|
// should stop blinking
|
||||||
|
blinkStart = null
|
||||||
|
lastKey = now
|
||||||
|
player.texture = resources['assets/player_still.png'].texture
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// is not blinking
|
||||||
|
player.texture = resources['assets/player_still_eyesclosed.png'].texture
|
||||||
|
blinkStart = now
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
container.x = -(player.x + player.width/2 - WIDTH/2)
|
||||||
|
|
||||||
|
if (player.x - player.width/2 < TARGET_AREA_WIDTH) {
|
||||||
|
player.x = TARGET_AREA_WIDTH + player.width/2
|
||||||
|
}
|
||||||
|
if (player.y - player.height/2 < 0) {
|
||||||
|
player.y = player.width/2
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.x + player.width/2 > maxX) {
|
||||||
|
player.x = maxX - player.width/2
|
||||||
|
}
|
||||||
|
if (player.y + player.height/2 > HEIGHT) {
|
||||||
|
player.y = HEIGHT - player.width/2
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const c of objects) {
|
||||||
|
if (c.type === 'cow') {
|
||||||
|
for (const w of objects) {
|
||||||
|
if (w.type === 'water' && hitTestRectangle(c, w)) {
|
||||||
|
w.ticks = Math.min(10, w.ticks)
|
||||||
|
w.ticks = Math.min(10, w.ticks)
|
||||||
|
|
||||||
|
c.ticks += 1
|
||||||
|
c.vrot = Math.random() > 0.5 ? 1 : -1
|
||||||
|
c.vx = Math.random() > 0.5 ? 1 : -1
|
||||||
|
c.vy = Math.random() > 0.5 ? 1 : -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.vx || player.vy) {
|
||||||
|
for (const obj of objects) {
|
||||||
|
if (hitTestRectangle(player, obj)) {
|
||||||
|
const dir = player.x > obj.x ? 1 : -1
|
||||||
|
obj.vrot = .1 * dir
|
||||||
|
obj.ticks += 3
|
||||||
|
|
||||||
|
obj.vx = player.x > obj.x ? -1 : 1
|
||||||
|
obj.vy = player.y > obj.y ? -1 : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (player.taps.pop()){
|
||||||
|
for (const obj of objects) {
|
||||||
|
if (hitTestRectangle(player, obj)) {
|
||||||
|
const dir = player.x > obj.x ? 1 : -1
|
||||||
|
obj.vrot = .1 * dir
|
||||||
|
obj.ticks += 10
|
||||||
|
|
||||||
|
if (player.x === obj.x) {
|
||||||
|
obj.vx = Math.random() >= 0.5 ? -1 : 1
|
||||||
|
} else {
|
||||||
|
obj.vx = player.x > obj.x ? -1 : 1
|
||||||
|
}
|
||||||
|
if (player.y === obj.y) {
|
||||||
|
obj.vy = Math.random() >= 0.5 ? -1 : 1
|
||||||
|
} else {
|
||||||
|
obj.vy = player.y > obj.y ? -1 : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let ptsWater = 0
|
||||||
|
let ptsCows = 0
|
||||||
|
for (const obj of objects) {
|
||||||
|
if (obj.ticks > 0) {
|
||||||
|
obj.rotation += Math.min(obj.ticks, 10) * obj.vrot
|
||||||
|
obj.x += obj.vx
|
||||||
|
obj.y += obj.vy
|
||||||
|
obj.ticks -= 1
|
||||||
|
|
||||||
|
if (obj.x - obj.width/2 < 0) {
|
||||||
|
obj.x = 0 + obj.width/2
|
||||||
|
}
|
||||||
|
if (obj.y - obj.height/2 < 0) {
|
||||||
|
obj.y = obj.width/2
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.x + obj.width/2 > maxX + TARGET_AREA_WIDTH) {
|
||||||
|
obj.x = (maxX + TARGET_AREA_WIDTH) - obj.width/2
|
||||||
|
}
|
||||||
|
if (obj.y + obj.height/2 > HEIGHT) {
|
||||||
|
obj.y = HEIGHT - obj.width/2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (obj.type === 'cow') {
|
||||||
|
if (obj.x > maxX) {
|
||||||
|
ptsCows ++
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.x < TARGET_AREA_WIDTH) {
|
||||||
|
// cant win :(
|
||||||
|
state = end
|
||||||
|
END_TXT.text = 'YOU LOSE!! >:('
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.type === 'water') {
|
||||||
|
if (obj.x < TARGET_AREA_WIDTH) {
|
||||||
|
ptsWater ++
|
||||||
|
}
|
||||||
|
if (obj.x > maxX) {
|
||||||
|
// cant win :(
|
||||||
|
state = end
|
||||||
|
END_TXT.text = 'YOU LOSE!! >:('
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PTS_WATER.text = `${ptsWater}/20`
|
||||||
|
PTS_COWS.text = `${ptsCows}/20`
|
||||||
|
}
|
||||||
|
if (PTS_WATER >= 20 && PTS_COWS >= 20) {
|
||||||
|
state = end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//The `keyboard` helper function
|
||||||
|
function keyboard(keyCode) {
|
||||||
|
var key = {};
|
||||||
|
key.code = keyCode;
|
||||||
|
key.isDown = false;
|
||||||
|
key.isUp = true;
|
||||||
|
key.press = undefined;
|
||||||
|
key.release = undefined;
|
||||||
|
//The `downHandler`
|
||||||
|
key.downHandler = event => {
|
||||||
|
if (event.keyCode === key.code) {
|
||||||
|
if (key.isUp && key.press) key.press();
|
||||||
|
key.isDown = true;
|
||||||
|
key.isUp = false;
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
};
|
||||||
|
|
||||||
|
//The `upHandler`
|
||||||
|
key.upHandler = event => {
|
||||||
|
if (event.keyCode === key.code) {
|
||||||
|
if (key.isDown && key.release) key.release();
|
||||||
|
key.isDown = false;
|
||||||
|
key.isUp = true;
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
};
|
||||||
|
|
||||||
|
//Attach event listeners
|
||||||
|
window.addEventListener(
|
||||||
|
"keydown", key.downHandler.bind(key), false
|
||||||
|
);
|
||||||
|
window.addEventListener(
|
||||||
|
"keyup", key.upHandler.bind(key), false
|
||||||
|
);
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hitTestRectangle(r1, r2) {
|
||||||
|
|
||||||
|
//Define the variables we'll need to calculate
|
||||||
|
let hit, combinedHalfWidths, combinedHalfHeights, vx, vy;
|
||||||
|
|
||||||
|
//hit will determine whether there's a collision
|
||||||
|
hit = false;
|
||||||
|
|
||||||
|
//Find the center points of each sprite
|
||||||
|
r1.centerX = r1.x + r1.width / 2;
|
||||||
|
r1.centerY = r1.y + r1.height / 2;
|
||||||
|
r2.centerX = r2.x + r2.width / 2;
|
||||||
|
r2.centerY = r2.y + r2.height / 2;
|
||||||
|
|
||||||
|
//Find the half-widths and half-heights of each sprite
|
||||||
|
r1.halfWidth = r1.width / 2;
|
||||||
|
r1.halfHeight = r1.height / 2;
|
||||||
|
r2.halfWidth = r2.width / 2;
|
||||||
|
r2.halfHeight = r2.height / 2;
|
||||||
|
|
||||||
|
//Calculate the distance vector between the sprites
|
||||||
|
vx = r1.centerX - r2.centerX;
|
||||||
|
vy = r1.centerY - r2.centerY;
|
||||||
|
|
||||||
|
//Figure out the combined half-widths and half-heights
|
||||||
|
combinedHalfWidths = r1.halfWidth + r2.halfWidth;
|
||||||
|
combinedHalfHeights = r1.halfHeight + r2.halfHeight;
|
||||||
|
|
||||||
|
//Check for a collision on the x axis
|
||||||
|
if (Math.abs(vx) < combinedHalfWidths) {
|
||||||
|
|
||||||
|
//A collision might be occurring. Check for a collision on the y axis
|
||||||
|
if (Math.abs(vy) < combinedHalfHeights) {
|
||||||
|
|
||||||
|
//There's definitely a collision happening
|
||||||
|
hit = true;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
//There's no collision on the y axis
|
||||||
|
hit = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
//There's no collision on the x axis
|
||||||
|
hit = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//`hit` will be either `true` or `false`
|
||||||
|
return hit;
|
||||||
|
};
|
||||||