Skip to content

Commit

Permalink
merge from master
Browse files Browse the repository at this point in the history
  • Loading branch information
Grafne23 committed Nov 5, 2018
2 parents 9badf93 + 68e2d9b commit 246810d
Show file tree
Hide file tree
Showing 8 changed files with 282 additions and 65 deletions.
10 changes: 0 additions & 10 deletions client/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import React from 'react';
import GameOverModal from './components/GameOverModal';
import WelcomeModal from './components/WelcomeModal';
import { drawGame, drawWalls } from './components/GameObjects';
import Minimap from './components/Minimap';
import Leaderboard from './components/Leaderboard';

import {
Expand Down Expand Up @@ -217,15 +216,6 @@ export default class App extends React.Component {
<div style={styles.canvasContainer}>
<Leaderboard players={this.state.players} />
<canvas id="ctx" style={styles.canvas} display="inline" width={window.innerWidth - 20} height={window.innerHeight - 20} margin={0} />
{
this.state.showMiniMap &&
<Minimap
arena={this.state.arena}
junk={this.state.junk}
players={this.state.players}
holes={this.state.holes}
/>
}
{
this.state.showWelcomeModal &&
<WelcomeModal
Expand Down
2 changes: 1 addition & 1 deletion client/components/GameObjects.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export function drawGame(data, canvas) {
});

const holes = data.holes.map((h) => {
if (!h.position) {
if (!h || !h.position) {
return {
position: { x: 0, y: 0 },
radius: 0,
Expand Down
4 changes: 2 additions & 2 deletions client/components/WelcomeModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ class WelcomeModal extends React.Component {
<ControlLabel> From</ControlLabel>

<FormControl componentClass="select" value={this.state.country} onChange={this.handleSelect}>
<option value="US" key="US">
{countries.US} {'US'.toUpperCase().replace(/./g, char => String.fromCodePoint(char.charCodeAt(0) + 127397))}
<option value="CA" key="CA">
{countries.CA} {'CA'.toUpperCase().replace(/./g, char => String.fromCodePoint(char.charCodeAt(0) + 127397))}
</option>
{listOfCountries}
</FormControl>
Expand Down
12 changes: 12 additions & 0 deletions server/arena/arena.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,18 @@ func (a *Arena) GetPlayerMessages() []*models.PlayerMessage {
return players
}

// GetPlayers returns a list of players
func (a *Arena) GetPlayers() []*models.Player {
a.rwMutex.RLock()
defer a.rwMutex.RUnlock()

players := make([]*models.Player, 0, len(a.Players))
for _, player := range a.Players {
players = append(players, player)
}
return players
}

// UpdatePositions calculates the next state of each object
func (a *Arena) UpdatePositions() {
a.rwMutex.Lock()
Expand Down
62 changes: 56 additions & 6 deletions server/models/hole.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package models
import (
"math"
"math/rand"
"sync"
)

// Hole related constants
Expand All @@ -23,6 +24,7 @@ type Hole struct {
IsAlive bool `json:"isAlive"`
Life float64 `json:"-"`
StartingLife float64 `json:"-"`
rwMutex sync.RWMutex
}

// HoleMessage contains the data the client needs about a hole
Expand All @@ -36,22 +38,70 @@ type HoleMessage struct {
func CreateHole(position Position) *Hole {
life := math.Floor(rand.Float64()*((MaxHoleLife-MinHoleLife)+1)) + MinHoleLife
radius := math.Floor(rand.Float64()*((MaxHoleRadius-MinHoleRadius)+1)) + MinHoleRadius
lock := sync.RWMutex{}
h := Hole{
PhysicsBody: CreateBody(position, radius, 0, 0),
PhysicsBody: CreateBody(position, radius, 0, 0, &lock),
GravityRadius: radius * gravityRadiusFactor,
Life: life,
IsAlive: false,
StartingLife: life,
rwMutex: lock,
}
return &h
}

// Getters
func (h *Hole) getLife() float64 {
h.rwMutex.RLock()
defer h.rwMutex.RUnlock()

return h.Life
}

func (h *Hole) getGravityRadius() float64 {
h.rwMutex.RLock()
defer h.rwMutex.RUnlock()

return h.GravityRadius
}

func (h *Hole) getStartingLife() float64 {
h.rwMutex.RLock()
defer h.rwMutex.RUnlock()

return h.StartingLife
}

// Setters
func (h *Hole) setIsAlive(isAlive bool) {
h.rwMutex.Lock()
defer h.rwMutex.Unlock()

h.IsAlive = isAlive
}

func (h *Hole) setLife(life float64) {
h.rwMutex.Lock()
defer h.rwMutex.Unlock()

h.Life = life
}

func (h *Hole) setGravityRadius(gravityRadius float64) {
h.rwMutex.Lock()
defer h.rwMutex.Unlock()

h.GravityRadius = gravityRadius
}

// Update reduces this holes life and increases radius if max not reached
func (h *Hole) Update() {
h.Life--
hLife := h.getLife()
hLife--
h.setLife(hLife)

if h.Life < h.StartingLife-HoleInfancy {
h.IsAlive = true
if hLife < h.getStartingLife()-HoleInfancy {
h.setIsAlive(true)
}
if h.GetRadius() < MaxHoleRadius*1.2 {
h.SetRadius(h.GetRadius() + 0.02)
Expand All @@ -61,7 +111,7 @@ func (h *Hole) Update() {

// IsDead checks the lifespan of the hole
func (h *Hole) IsDead() bool {
return h.Life < 0
return h.getLife() < 0
}

// ApplyGravity modifies given velocity based on given position and damping factor relative to this hole.
Expand All @@ -76,7 +126,7 @@ func (h *Hole) ApplyGravity(b1 *PhysicsBody, DampingFactor float64) {

//Velocity is affected by how close you are, the size of the hole, and a damping factor.
gravityVector.ApplyFactor(inverseMagnitude * h.GetRadius() * DampingFactor)
b1.Velocity.ApplyVector(gravityVector)
b1.ApplyVector(gravityVector)
}

// MakeMessage returns a HoleMessage with this hole's data
Expand Down
103 changes: 86 additions & 17 deletions server/models/junk.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package models

import (
"sync"
)

// Junk related constants
const (
JunkFriction = 0.98
Expand All @@ -17,6 +21,7 @@ type Junk struct {
LastPlayerHit *Player `json:"-"`
Debounce int `json:"-"`
jDebounce int
rwMutex sync.RWMutex
}

// JunkMessage contains the data the client needs about a junk
Expand All @@ -28,14 +33,60 @@ type JunkMessage struct {

// CreateJunk initializes and returns an instance of a Junk
func CreateJunk(position Position) *Junk {
lock := sync.RWMutex{}
return &Junk{
PhysicsBody: CreateBody(position, JunkRadius, JunkMass, JunkRestitutionFactor),
PhysicsBody: CreateBody(position, JunkRadius, JunkMass, JunkRestitutionFactor, &lock),
Color: "white",
Debounce: 0,
jDebounce: 0,
rwMutex: lock,
}
}

// Getters
func (j *Junk) getDebounce() int {
j.rwMutex.RLock()
defer j.rwMutex.RUnlock()

return j.Debounce
}

func (j *Junk) getJDebounce() int {
j.rwMutex.RLock()
defer j.rwMutex.RUnlock()

return j.jDebounce
}

// Setters
func (j *Junk) setDebounce(debounce int) {
j.rwMutex.Lock()
defer j.rwMutex.Unlock()

j.Debounce = debounce
}

func (j *Junk) setJDebounce(jDebounce int) {
j.rwMutex.Lock()
defer j.rwMutex.Unlock()

j.jDebounce = jDebounce
}

func (j *Junk) setColor(color string) {
j.rwMutex.Lock()
defer j.rwMutex.Unlock()

j.Color = color
}

func (j *Junk) setLastPlayerHit(player *Player) {
j.rwMutex.Lock()
defer j.rwMutex.Unlock()

j.LastPlayerHit = player
}

// UpdatePosition Update Junk's position based on calculations of position/velocity
func (j *Junk) UpdatePosition(height float64, width float64) {
// Check if the junk should reflect off the walls first
Expand All @@ -49,44 +100,44 @@ func (j *Junk) UpdatePosition(height float64, width float64) {
j.ApplyFactor(JunkFriction)
j.ApplyVelocity()

if j.Debounce > 0 {
j.Debounce--
if jDebounce := j.getDebounce(); jDebounce > 0 {
j.setDebounce(jDebounce - 1)
} else {
j.Debounce = 0
j.setDebounce(0)
}

if j.jDebounce > 0 {
j.jDebounce--
if jjDebounce := j.getJDebounce(); jjDebounce > 0 {
j.setJDebounce(jjDebounce - 1)
} else {
j.jDebounce = 0
j.setJDebounce(0)
}
}

// HitBy causes a collision event between this junk and given player.
func (j *Junk) HitBy(p *Player) {
pVelocity := p.getVelocity()
// We don't want this collision till the debounce is down.
if j.Debounce != 0 {
// We don't want this collision till the debounce is done.
if j.getDebounce() != 0 {
return
}

j.Color = p.getColor() //Assign junk to last recently hit player color
j.LastPlayerHit = p
j.setColor(p.getColor()) //Assign junk to last recently hit player color
j.setLastPlayerHit(p)

InelasticCollision(&j.PhysicsBody, &p.PhysicsBody)

j.Debounce = JunkDebounceTicks
j.setDebounce(JunkDebounceTicks)
}

// HitJunk causes a collision event between this junk and given junk.
func (j *Junk) HitJunk(jh *Junk) {
// We don't want this collision till the debounce is down.
if j.jDebounce != 0 {
// We don't want this collision till the debounce is done.
if j.getJDebounce() != 0 {
return
}
InelasticCollision(&j.PhysicsBody, &jh.PhysicsBody)

j.jDebounce = JunkDebounceTicks
jh.jDebounce = JunkDebounceTicks
j.setJDebounce(JunkDebounceTicks)
jh.setJDebounce(JunkDebounceTicks)
}

// MakeMessage returns a JunkMessage with this junk's data
Expand All @@ -97,3 +148,21 @@ func (j *Junk) MakeMessage() *JunkMessage {
Color: j.Color,
}
}

// ApplyGravity Applys a vector towards given position
func (j *Junk) ApplyGravity(h *Hole) {
jVelocity := j.GetVelocity()
jPosition := j.GetPosition()
hPosition := h.GetPosition()

gravityVector := Velocity{0, 0}
gravityVector.Dx = hPosition.X - jPosition.X
gravityVector.Dy = hPosition.Y - jPosition.Y
inverseMagnitude := 1.0 / gravityVector.magnitude()
gravityVector.normalize()

//Velocity is affected by how close you are, the size of the hole, and a damping factor.
jVelocity.Dx += gravityVector.Dx * inverseMagnitude * h.GetRadius() * JunkGravityDamping
jVelocity.Dy += gravityVector.Dy * inverseMagnitude * h.GetRadius() * JunkGravityDamping
j.SetVelocity(jVelocity)
}
Loading

0 comments on commit 246810d

Please sign in to comment.