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;
|
||||
};
|
||||