Created
August 7, 2017 17:18
-
-
Save moduscreate/417911e6ec522e3a2947391e0f0cc03c to your computer and use it in GitHub Desktop.
Full file for React Native Shooter, EVADE (prototype).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react'; | |
import { | |
AppRegistry, | |
StyleSheet, | |
Text, | |
View, | |
Image, | |
Dimensions, | |
PanResponder | |
} from 'react-native'; | |
const dimensions = Dimensions.get('window'), | |
halfScreenWidth = dimensions.width / 2; | |
var { | |
MCModPlayerInterface | |
} = require('NativeModules'); | |
import GLOBALS from './Globals'; | |
import Enemy from './Enemy'; | |
import Boss1 from './Boss1'; | |
import Boss2 from './Boss2'; | |
import Boss3 from './Boss3'; | |
import EnemyBullet from './EnemyBullet'; | |
//import Controller from './Controller'; | |
import Starfield from './Starfield'; | |
import Player from './Player'; | |
import PlayerBullet from './PlayerBullet'; | |
import StatusBar from './StatusBar'; | |
export default class EVADE extends Component { | |
enemies = []; | |
enemyBullets = []; | |
/* Used to track multi-touch gestures */ | |
movePlayerX = null; | |
movePlayerY = null; | |
movePlayer = true; | |
numTouches = -1; // -1 not touching, 1: One finger fire laser, 2: double touch -> fire blast! | |
constructor(props) { | |
super(props); | |
this.state = {}; | |
} | |
respondTrue = (evt, gestureState) => true; | |
componentWillMount() { | |
this.panResponder = PanResponder.create({ | |
// Ask to be the responder: | |
onStartShouldSetPanResponder : this.respondTrue, | |
onStartShouldSetPanResponderCapture : this.respondTrue, | |
onMoveShouldSetPanResponder : this.respondTrue, | |
onMoveShouldSetPanResponderCapture : this.respondTrue, | |
onPanResponderGrant : this.onPanResponderGrant, | |
onPanResponderMove : this.onPanResponderMove, | |
onPanResponderTerminationRequest : this.respondTrue, | |
onPanResponderRelease : this.onPanResponderRelease, | |
onPanResponderTerminate : this.onPanResponderRelease | |
}) | |
} | |
onPanResponderGrant = (evt, gestureState) => { | |
const { nativeEvent } = evt, | |
{ | |
identifier, | |
touches | |
} = nativeEvent; | |
if (identifier > 2) { | |
return; | |
} | |
this.numTouches = touches.length | |
if (! this.movePlayerTouchID) { | |
this.movePlayerTouchID = identifier; | |
this.movePlayerX = gestureState.x0; | |
this.movePlayerY = gestureState.y0; | |
} | |
else if (identifier == this.movePlayerTouchID) { | |
this.movePlayerX = gestureState.moveX; | |
this.movePlayerY = gestureState.moveY; | |
} | |
} | |
onPanResponderMove = (evt, gestureState) => { | |
// console.log(JSON.stringify(gestureState, null,4)) | |
// The most recent move distance is gestureState.move{X,Y} | |
// The accumulated gesture distance since becoming responder is | |
// gestureState.d{x,y} | |
const { nativeEvent } = evt, | |
{ | |
identifier, | |
touches | |
} = nativeEvent; | |
if (identifier > 2) { | |
return; | |
} | |
this.numTouches = touches.length | |
if (identifier == this.movePlayerTouchID) { | |
this.movePlayerX = gestureState.moveX; | |
this.movePlayerY = gestureState.moveY; | |
} | |
} | |
onPanResponderRelease = (evt, gestureState) => { | |
// The user has released all touches while this view is the | |
// responder. This typically means a gesture has succeeded | |
const { nativeEvent } = evt, | |
{ | |
identifier, | |
touches | |
} = nativeEvent; | |
if (identifier > 2) { | |
return; | |
} | |
this.numTouches = touches.length | |
if (identifier == this.movePlayerTouchID) { | |
this.movePlayerTouchID = null; | |
this.movePlayerX = null; | |
this.movePlayerY = null; | |
} | |
} | |
componentDidMount() { | |
setTimeout(this.run, 10); | |
} | |
handleControls() { | |
var buttonState = this.buttonState, | |
player = this.player; | |
if (buttonState.up) { | |
player.moveUp(); | |
} | |
if (buttonState.down) { | |
player.moveDown(); | |
} | |
if (buttonState.left) { | |
player.moveLeft(); | |
} | |
if (buttonState.right) { | |
player.moveRight() | |
} | |
if (buttonState.fireA) { | |
player.fireA(); | |
} | |
if (buttonState.fireB) { | |
player.fireB(); | |
} | |
} | |
checkImpactOnPlayer(enemyBullet, player) { | |
if (enemyBullet.checkImpact(player)) { | |
player.takeDamage(); | |
GLOBALS.LIVES_REMAIN--; | |
MCModPlayerInterface.sfx('explodePlayer', true); | |
if (GLOBALS.LIVES_REMAIN < 0) { | |
GLOBALS.GAME_OVER_FRAME = GLOBALS.CURRENT_FRAME; | |
console.log('GAME OVER!') | |
} | |
else { | |
this.statusBar.updateLives(); | |
} | |
} | |
} | |
updateScore(newScore) { | |
if (newScore > GLOBALS.PLAYER_SCORE) { | |
GLOBALS.PLAYER_SCORE = newScore; | |
this.statusBar.updateScore(); | |
} | |
} | |
stepPlayer() { | |
var playerScore = GLOBALS.PLAYER_SCORE; | |
const { player, playerBullet1, playerBullet2 } = this; | |
player.update(); | |
// If touch is happening, and the player is not dead and hte player is not dying and the last life is not lost | |
if (this.movePlayerTouchID && ! player.isDead && player.dying == 0 && GLOBALS.GAME_OVER_FRAME == -1) { | |
player.stepTo(this.movePlayerX, this.movePlayerY); | |
let {x, y, halfHeight, halfWidth} = player, | |
shootX = x + halfWidth, | |
shootY = y + halfHeight; | |
if (! playerBullet1.isVisible()) { | |
playerBullet1.shoot(shootX, shootY); | |
} | |
// if (! playerBullet2.isVisible() && GLOBALS.CURRENT_GUN_CHARGE >= GLOBALS.GUN_SHOT_COST) { | |
// playerBullet2.shoot(x + halfWidth, y + halfHeight); | |
// GLOBALS.CURRENT_GUN_CHARGE -= GLOBALS.GUN_SHOT_COST; | |
// if (GLOBALS.CURRENT_GUN_CHARGE < 0) { | |
// GLOBALS.CURRENT_GUN_CHARGE = 0; | |
// } | |
// } | |
} | |
playerBullet2.update(); | |
playerBullet1.update(); | |
// Handle score | |
if (GLOBALS.CURRENT_FRAME % GLOBALS.PLAYER_POINT_FRAME_MOD == 0) { | |
playerScore++; | |
} | |
// Handle gun charge stuff. | |
this.handleGunRecharge(); | |
} | |
stepEnemies() { | |
var playerScore = GLOBALS.PLAYER_SCORE; | |
const { player, playerBullet1, playerBullet2 } = this; | |
const { boss1, boss2, boss3, boss1Bullet } = this; | |
/* Handle enemies */ | |
var numVisibleEnemies = 0; | |
this.enemies.forEach((enemy, index) => { | |
const enemyBullet = this.enemyBullets[index]; | |
if (playerBullet1.checkImpact(enemy)) { | |
playerBullet1.hide(); | |
playerScore += GLOBALS.BULLET1_DAMAGE; | |
let isDead = enemy.takeDamage(GLOBALS.BULLET1_DAMAGE); | |
if (isDead) { | |
GLOBALS.NUM_KILLS++; | |
playerScore += GLOBALS[enemy.healthType]; | |
MCModPlayerInterface.sfx('explodeEnemy', true); | |
} | |
} | |
if (playerBullet2.checkImpact(enemy)) { | |
playerBullet2.hide(); | |
playerScore += GLOBALS.BULLET2_DAMAGE; | |
let isDead = enemy.takeDamage(GLOBALS.BULLET2_DAMAGE); | |
if (isDead) { | |
GLOBALS.NUM_KILLS++; | |
playerScore += GLOBALS[enemy.healthType]; | |
MCModPlayerInterface.sfx('explodeEnemy', true); | |
} | |
} | |
var shouldShoot = enemy.update(); | |
if (shouldShoot) { | |
let {x, y, halfHeight, width} = enemy; | |
enemyBullet.shoot(x, y + halfHeight); | |
} | |
enemyBullet.update(); | |
this.checkImpactOnPlayer(enemyBullet, player); | |
if (enemy.isVisible()) { | |
numVisibleEnemies++; | |
} | |
}); | |
this.updateScore(playerScore); | |
GLOBALS.NUM_VISIBLE_ENEMIES = numVisibleEnemies; | |
} | |
// TODO: Split Step() into 3 functions: stepPlayer, stepEnemies, stepBosses | |
stepBoss() { | |
const { GAME_LEVEL, NUM_VISIBLE_ENEMIES, BOSS_LEVEL } = GLOBALS; | |
const allEnemiesDead = NUM_VISIBLE_ENEMIES == 0; | |
const { | |
boss1, | |
boss2, | |
boss3, | |
boss1Bullet, | |
player, | |
playerBullet1, | |
playerBullet2 | |
} = this; | |
boss1Bullet.update(); | |
this.checkImpactOnPlayer(boss1Bullet, player); | |
if (GLOBALS.BOSS_LEVEL == 0 || allEnemiesDead == false) { | |
return; | |
} | |
var playerScore = GLOBALS.PLAYER_SCORE; | |
// if (noVisibleEnemies) { | |
// bossToSpawn = 1; | |
// } | |
// else if (GLOBALS.GAME_LEVEL == 2 && allEnemiesDead) { | |
// bossToSpawn = 2; | |
// } | |
// else if (GLOBALS.GAME_LEVEL == 3 && allEnemiesDead) { | |
// bossToSpawn = 3; | |
// } | |
/* Handle bosses */ | |
// TODO: REfactor so it's not so much copy/paste code!!!! -- JG | |
if (BOSS_LEVEL == 1) { | |
let shouldShoot = boss1.update(); | |
if (shouldShoot) { | |
let {x, y, halfHeight, width} = boss1; | |
boss1Bullet.shoot(x, y + halfHeight); | |
} | |
if (boss1.inPlay) { | |
if (playerBullet1.checkImpact(boss1)) { | |
playerScore += GLOBALS.BULLET1_DAMAGE; | |
let isDying = boss1.takeDamage(GLOBALS.BULLET1_DAMAGE); | |
if (isDying) { | |
playerScore += GLOBALS.BOSS_1_HEALTH; | |
MCModPlayerInterface.sfx('explodeEnemy', true); | |
} | |
} | |
if (playerBullet2.checkImpact(boss1)) { | |
playerScore += GLOBALS.BULLET2_DAMAGE; | |
let isDying = boss1.takeDamage(GLOBALS.BULLET2_DAMAGE); | |
if (isDying) { | |
playerScore += GLOBALS.BOSS_1_HEALTH; | |
MCModPlayerInterface.sfx('explodeEnemy', true); | |
} | |
} | |
} | |
if (boss1.isDead && boss1.dying == 0) { | |
console.log('BOSS1 Is dead!!') | |
GLOBALS.BOSS_ALIVE = false; | |
GLOBALS.GAME_LEVEL++; | |
GLOBALS.NUM_KILLS = 0; | |
GLOBALS.BOSS_LEVEL = 0; | |
GLOBALS.STOP_SPAWNING_ENEMIES = false; | |
} | |
} | |
else { | |
boss1.offScreen = true; | |
boss1.hide(); | |
} | |
if (GAME_LEVEL == 2) { | |
let shouldShoot = boss2.update(); | |
if (shouldShoot) { | |
let {x, y, halfHeight} = boss2; | |
boss1Bullet.shoot(x, y + halfHeight); | |
} | |
if (boss2.inPlay) { | |
if (playerBullet1.checkImpact(boss2)) { | |
playerScore += GLOBALS.BULLET1_DAMAGE; | |
let isDying = boss2.takeDamage(GLOBALS.BULLET1_DAMAGE); | |
if (isDying) { | |
playerScore += GLOBALS.BOSS_1_HEALTH; | |
MCModPlayerInterface.sfx('explodeEnemy', true); | |
} | |
} | |
if (playerBullet2.checkImpact(boss2)) { | |
playerScore += GLOBALS.BULLET2_DAMAGE; | |
let isDying = boss2.takeDamage(GLOBALS.BULLET2_DAMAGE); | |
if (isDying) { | |
playerScore += GLOBALS.BOSS_2_HEALTH; | |
MCModPlayerInterface.sfx('explodeEnemy', true); | |
} | |
} | |
} | |
if (boss2.isDead && boss2.dying == 0) { | |
console.log('BOSS2 Is dead!!') | |
GLOBALS.BOSS_ALIVE = false; | |
GLOBALS.GAME_LEVEL++; | |
GLOBALS.NUM_KILLS = 0; | |
GLOBALS.BOSS_LEVEL = 0; | |
GLOBALS.STOP_SPAWNING_ENEMIES = false; | |
} | |
} | |
else { | |
boss2.offScreen = true; | |
boss2.hide(); | |
} | |
// TODO: Needs 2x bullets! | |
if (GAME_LEVEL == 3) { | |
let shouldShoot = boss3.update(); | |
if (shouldShoot) { | |
let {x, y, halfHeight} = boss3; | |
boss1Bullet.shoot(x, y + halfHeight); | |
} | |
if (boss3.inPlay) { | |
if (playerBullet1.checkImpact(boss3)) { | |
playerScore += GLOBALS.BULLET1_DAMAGE; | |
let isDying = boss3.takeDamage(GLOBALS.BULLET1_DAMAGE); | |
if (isDying) { | |
playerScore += GLOBALS.BOSS_3_HEALTH; | |
MCModPlayerInterface.sfx('explodeEnemy', true); | |
} | |
} | |
if (playerBullet2.checkImpact(boss3)) { | |
playerScore += GLOBALS.BULLET2_DAMAGE; | |
let isDying = boss3.takeDamage(GLOBALS.BULLET2_DAMAGE); | |
if (isDying) { | |
playerScore += GLOBALS.BOSS_3_HEALTH; | |
MCModPlayerInterface.sfx('explodeEnemy', true); | |
} | |
} | |
} | |
if (boss3.isDead && boss3.dying == 0) { | |
console.log('BOSS3 Is dead!!') | |
GLOBALS.BOSS_ALIVE = false; | |
GLOBALS.NEXT_ITERATION_FRAME = GLOBALS.CURRENT_FRAME; | |
GLOBALS.GAME_LEVEL++; | |
GLOBALS.NUM_KILLS = 0; | |
GLOBALS.BOSS_LEVEL = 0; | |
GLOBALS.STOP_SPAWNING_ENEMIES = false; | |
} | |
} | |
else { | |
// if (boss3.isDead && boss3.dying == 0) { | |
// console.log('BOSS3 is f\'ing dead') | |
// GLOBALS.BOSS_ALIVE = false; | |
// GLOBALS.GAME_LEVEL = 4; | |
// GLOBALS.NUM_KILLS = 0; | |
// boss3.hide(); | |
// } | |
// boss3.updateDeathSequence(); | |
// boss3.offScreen = true; | |
// boss3.update(); | |
// boss3.hide(); | |
} | |
// if (playerScore > GLOBALS.PLAYER_SCORE) { | |
// GLOBALS.PLAYER_SCORE = playerScore; | |
// this.statusBar.updateScore(); | |
// } | |
this.updateScore(playerScore); | |
} | |
handleGunRecharge() { | |
if (GLOBALS.CURRENT_FRAME % 5 == 0 && GLOBALS.CURRENT_GUN_CHARGE < GLOBALS.MAX_GUN_CHARGE) { | |
GLOBALS.CURRENT_GUN_CHARGE++; | |
if (GLOBALS.CURRENT_GUN_CHARGE > GLOBALS.MAX_GUN_CHARGE) { | |
GLOBALS.CURRENT_GUN_CHARGE = GLOBALS.MAX_GUN_CHARGE; | |
} | |
this.statusBar.updatePewBar(); | |
} | |
} | |
run = () => { | |
if (GLOBALS.GAME_IN_PLAY) { | |
GLOBALS.CURRENT_FRAME++; | |
// var playerScore = GLOBALS.PLAYER_SCORE; | |
const player = this.player, | |
gameLevel = GLOBALS.GAME_LEVEL; | |
this.starfield.step(); | |
this.stepPlayer(); | |
if (gameLevel == 1 && GLOBALS.NUM_KILLS >= GLOBALS.BOSS1_MIN_KILLS) { | |
GLOBALS.BOSS_LEVEL = 1; | |
GLOBALS.STOP_SPAWNING_ENEMIES = true; | |
} | |
else if (gameLevel == 2 && GLOBALS.NUM_KILLS >= GLOBALS.BOSS2_MIN_KILLS) { | |
GLOBALS.BOSS_LEVEL = 2; | |
GLOBALS.STOP_SPAWNING_ENEMIES = true; | |
} | |
else if (gameLevel == 3 && GLOBALS.NUM_KILLS >= GLOBALS.BOSS3_MIN_KILLS) { | |
GLOBALS.BOSS_LEVEL = 3; | |
GLOBALS.STOP_SPAWNING_ENEMIES = true; | |
} | |
else if (gameLevel == 4) { | |
if (GLOBALS.CURRENT_FRAME - GLOBALS.NEXT_ITERATION_FRAME >= 200) { | |
GLOBALS.GAME_IN_PLAY = false; | |
return; | |
} | |
} | |
else { | |
GLOBALS.BOSS_LEVEL = 0; | |
} | |
if (gameLevel < 4) { | |
this.stepEnemies(); | |
this.stepBoss(); | |
} | |
// Handle the countdown to the last few frames | |
if (GLOBALS.GAME_OVER_FRAME > -1) { | |
if (GLOBALS.CURRENT_FRAME - GLOBALS.GAME_OVER_FRAME >= 150) { | |
GLOBALS.GAME_IN_PLAY = false; | |
} | |
} | |
requestAnimationFrame(this.run); | |
} | |
else { | |
console.log('GLOBALS.GAME_LEVEL', GLOBALS.GAME_LEVEL) | |
if (GLOBALS.GAME_LEVEL < 4) { | |
console.log("GAME OVER!!!") | |
} | |
else { | |
console.log('NEXT Level!!') | |
} | |
} | |
} | |
buttonState = { | |
up : false, | |
down : false, | |
left : false, | |
right : false, | |
fireA : false, | |
fireB : false | |
} | |
onPress = (buttonType, pressed) => { | |
this.buttonState[buttonType] = pressed; | |
// this.setState({ | |
// info : JSON.stringify(this.buttonState, null, 4) | |
// }) | |
} | |
render() { | |
var enemies = [], | |
enemyBullets = []; | |
for (var i = 0; i < GLOBALS.MAX_ENEMIES; i++) { | |
enemies.push(<EnemyBullet speed={20} bulletType={3} key={`enemyBullet${i}`} ref={c => this.enemyBullets.push(c) }/>); | |
enemies.push(<Enemy key={`enemy${i}`} ref={c => this.enemies.push(c)}/>); | |
} | |
const statusBarStyle = { | |
height : GLOBALS.STATUS_BAR_HEIGHT, | |
// backgroundColor : 'rgba(0,0,255,.3)', | |
width : dimensions.width, | |
position : 'absolute', | |
top : 0, | |
left : 0 | |
} | |
return ( | |
<View style={styles.container}> | |
{/* Top section for lives, charge meter, score, pause button */} | |
<StatusBar style={statusBarStyle} ref={c => this.statusBar = c} /> | |
{/* Rest of the gameboard. Player, enemies, bosses, Starfield */} | |
<View style={{flex:1}} {...this.panResponder.panHandlers}> | |
<Starfield ref={c => this.starfield = c}/> | |
{/* | |
<View style={{backgroundColor : 'rgba(255, 255, 255, .01)', height : 225, width : dimensions.width}}> | |
<Text style={{fontSize: 15, color : '#FFF'}}> | |
{this.state.info || ''} | |
</Text> | |
</View> | |
*/} | |
<PlayerBullet bulletType={1} speed={25} ref={c => this.playerBullet1 = c}/> | |
<PlayerBullet bulletType={2} speed={20} ref={c => this.playerBullet2 = c}/> | |
{enemies} | |
{enemyBullets} | |
{/* TODO: Refactor Boss classses so that it is one component and not 3 */} | |
<Boss1 ref={c => this.boss1 = c}/> | |
<Boss2 ref={c => this.boss2 = c}/> | |
<Boss3 ref={c => this.boss3 = c}/> | |
<EnemyBullet ref={c => this.boss1Bullet = c}/> | |
<Player ref={c => this.player = c}/> | |
{/* <Controller onPress={this.onPress}/> */} | |
</View> | |
</View> | |
); | |
} | |
} | |
const styles = StyleSheet.create({ | |
container : { | |
flex : 1, | |
// borderWidth : 1, borderColor: '#0F0' | |
} | |
}); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment