Skip to content

Commit

Permalink
Some documentation and cleanup of warnings.
Browse files Browse the repository at this point in the history
  • Loading branch information
j14159 committed Mar 4, 2013
1 parent 75e6730 commit 1aeae75
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 45 deletions.
10 changes: 9 additions & 1 deletion src/movement.erl
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,19 @@
-include_lib("eunit/include/eunit.hrl").
-endif.

%%%----------------------------------------------------------------------
%%%
%%% "movement" is one of the earliest modules in this project and it
%%% probably shows. Functions here assist in calculating vectors based
%%% on current player attitude, assist with upper bounds on vectors and
%%% simple 2x2 matrix addition.
%%%
%%%----------------------------------------------------------------------

radians(Degrees) ->
3.14159 * Degrees / 180.

degrees(Radians) ->
%Radians * 0.017453292519.
Radians * 180 / 3.14159.

startMatrix(X, Y) ->
Expand Down
6 changes: 0 additions & 6 deletions src/player.erl
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,10 @@ player(Master, {X, Y, Heading}, Vector, UpdateVector, LiveTorps, Xsize, Ysize) -
{{_, _}, {NvX, NvY}} = movement:addMatrix(Vector, movement:nextMatrix(scaled, Heading, 1, X, Y)),
Vec = {{X, Y}, {NvX, NvY}},
gen_server:cast(play_space, {self(), X, Y, Heading, Vec}),
%player(Master, {X, Y, Heading}, {{X, Y},
% {movement:clampVector(NvX),
% movement:clampVector(NvY)}}, done, LiveTorps, Xsize, Ysize);
player(Master, {X, Y, Heading}, Vector, done, LiveTorps, Xsize, Ysize);
torp when LiveTorps < 3 ->
Torp = spawn(torps, torp, [self()]),
TorpVec = movement:nextMatrix(torp, Heading, 8, X, Y),
% this is a gross way to place the torp, needs fixing
%Tv = movement:addMatrix(movement:addMatrix(movement:addMatrix(Vector, TorpVec), TorpVec), TorpVec),
{Tx1, Ty1} = move(X, Y, TorpVec, 4),

gen_server:cast(play_space, {torp, {Torp, Tx1, Ty1, 0, TorpVec}}),
Expand Down Expand Up @@ -102,7 +97,6 @@ entity_struct(X, Y, Z) ->

group_struct(Group) ->
Compacted = [{X, Y, Z} || {_, X, Y, Z, _} <- Group],
%{struct, lists:map(fun({X, Y, Z}) -> entity_struct(X, Y, Z) end, Compacted)}.
lists:map(fun({X, Y, Z}) -> entity_struct(X, Y, Z) end, Compacted).

% used when a player is dead/inactive:
Expand Down
8 changes: 7 additions & 1 deletion src/score_board.erl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, code_change/3, terminate/2]).
-compile([{parse_transform, lager_transform}]).

%%%----------------------------------------------------------------------
%%%
%%% "score_board" is just what the name suggests, in addition to being
%%% the central player registry.
%%%
%%%----------------------------------------------------------------------
init([]) ->
{ok, []}.

Expand Down Expand Up @@ -75,7 +81,7 @@ broadcast_score(State) ->
attempt_join(WsPid, NewName, State) ->
Existing = [N || {N, _, _} <- State, N =:= NewName],
case Existing of
[H | T] when H == NewName ->
[H | _] when H == NewName ->
{not_available, State};
_ ->
NewPid = spawn(player, player, [WsPid, 500, 800]),
Expand Down
49 changes: 32 additions & 17 deletions src/space.erl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, code_change/3, terminate/2]).
-compile([{parse_transform, lager_transform}]).

%%%----------------------------------------------------------------------
%%%
%%% "space" module is where the core movement and collision logic all
%%% takes place. It is responsible for enforcing the basic game physics
%%% and ultimately governs combat/kill resolution.
%%%
%%%----------------------------------------------------------------------

init([Xsize, Ysize]) ->
timer:send_after(50, update),
{ok, {Xsize, Ysize, [], []}}.
Expand All @@ -15,7 +23,10 @@ handle_cast({dead_torp, Pid}, {Xsize, Ysize, Players, Torps}) ->
{noreply, {Xsize, Ysize, Players, LiveTorps}};

handle_cast({dead, Pid}, {Xsize, Ysize, Players, Torps}) ->
% heavier logging here to track down phantom player bug
lager:info("space will remove pid ~w as dead, pre-filter player length is ~w", [Pid, length(Players)]),
Filtered = [{P, XX, YY, ZZ, V} || {P, XX, YY, ZZ, V} <- Players, P /= Pid],
lager:info("post-filter player length is ~w", [length(Filtered)]),
{noreply, {Xsize, Ysize, Filtered, Torps}};

handle_cast({Pid, X, Y, Z, Vec}, {Xsize, Ysize, Players, Torps}) ->
Expand Down Expand Up @@ -61,12 +72,12 @@ handle_info(update, {Xsize, Ysize, Players, Torps}) ->
code_change(PrevVersion, State, Extra) ->
{ok, State}.

terminate(Reason, State) ->
terminate(Reason, _) ->
ok.

%returns {moved and live players, players who collided with other players}
%% returns {moved and live players, players who collided with other players}
moved_and_suicides(Players, Xsize, Ysize) ->
Move = fun({P, X, Y, Z, V}) -> move_entity(P, X, Y, Z, planet_influence(X, Y, V, 8, Xsize, Ysize), Xsize, Ysize) end,
Move = fun({P, X, Y, Z, V}) -> move_entity(P, X, Y, Z, planet_influence(X, Y, V, 8), Xsize, Ysize) end,

MovedPlayers = lists:map(Move, Players),
% now check collisions:
Expand All @@ -76,25 +87,27 @@ moved_and_suicides(Players, Xsize, Ysize) ->
NotSuicided = filter_dead(Suicided, MovedPlayers),
{NotSuicided, Suicided}.

%% figures out which torpedoes are still live, which have hit players and planet,
%% which players have been killed.
torping_and_torped(Torps, Players, Xsize, Ysize) ->
Move = fun({P, X, Y, Z, V}) -> move_entity(P, X, Y, Z, planet_influence(X, Y, V, 20, Xsize, Ysize), Xsize, Ysize) end,
Move = fun({P, X, Y, Z, V}) -> move_entity(P, X, Y, Z, planet_influence(X, Y, V, 20), Xsize, Ysize) end,
MovedTorps = lists:map(Move, Torps),
{Torped, HitTorps} = collisions(Players, MovedTorps, [], []),
{StillTorping, PlanetTorps} = planet_impacts(20, filter_dead(HitTorps, MovedTorps), [], []),

{StillTorping, HitTorps, PlanetTorps, Torped}.

% change an entities vector based on planetary gravity.
planet_influence(X, Y, Vec, Mass, SpaceW, SpaceH) ->
%% change an entities vector based on planetary gravity.
planet_influence(X, Y, Vec, Mass) ->
Distance = math:sqrt((X * X) + (Y * Y)),
PlanetEffect = ((Mass * 1) / (Distance * Distance)),
{FullX, FullY} = {0 - X, 0 - Y},
PlanetVector = {{X, Y}, {PlanetEffect * FullX, PlanetEffect * FullY}},
movement:addMatrix(Vec, PlanetVector).

% takes a list of entities (ships/torps) and recursively checks to see which
% ones are OK and which ones hit the planet.
planet_impacts(PlanetSize, [], Ok, Dead) ->
%% takes a list of entities (ships/torps) and recursively checks to see which
%% ones are OK and which ones hit the planet.
planet_impacts(_, [], Ok, Dead) ->
{Ok, Dead};
planet_impacts(PlanetSize, [Entity | Rest], Ok, Dead) ->
case planet_impact(Entity, PlanetSize) of
Expand All @@ -113,8 +126,8 @@ planet_impact(Entity, PSize) ->
ok
end.

% finds all ships involved in collisions, sub-optimal, runs in O(n^2) at best:
collisions([], Players, Dead, ToRemove) ->
%% finds all entities involved in collisions, sub-optimal, runs in O(n^2) at best:
collisions([], _, Dead, ToRemove) ->
{Dead, ToRemove};
collisions([Ship | Rest], Players, Dead, ToRemove) ->
NewDead = collision_check(Ship, [P || P <- Players, P /= Ship]),
Expand All @@ -125,27 +138,27 @@ collisions([Ship | Rest], Players, Dead, ToRemove) ->
collisions(Rest, Players, [Ship | Dead], [Remove | ToRemove])
end.

% checks an individual ship for collisions against the others:
%% checks an individual entity for collisions against the others:
collision_check(Ship, Others) ->
{Pid, X, Y, _, _} = Ship,
{_, X, Y, _, _} = Ship,
Hits = [{P, X2, Y2 ,Z2, V} || {P, X2, Y2, Z2, V} <- Others, abs(X - X2) =< 5, abs(Y - Y2) =< 5],
case Hits of
[H | T] ->
[H | _] ->
io:format("Impacting object ~w~n", [H]),
{Ship, H};
_ ->
{none, []}
end.

% filters the list of dead players out of active ones
%% filters the list of dead entities out of active ones
filter_dead([], Players) ->
Players;
filter_dead([FirstDead | Rest], Players) ->
{DeadPid, _, _, _, _} = FirstDead,
Filtered = [{Pid, X, Y, Z, V} || {Pid, X, Y, Z, V} <- Players, Pid /= DeadPid],
filter_dead(Rest, Filtered).

% recurses through player list to broadcast enemy locations:
%% recurses through player list to broadcast enemy and torpedo locations:
msg_players([], _, _) ->
[];
msg_players([P | Rest], Players, Torps) ->
Expand All @@ -155,11 +168,13 @@ msg_players([P | Rest], Players, Torps) ->
Pid ! Msg,
msg_players(Rest, Players, Torps).

%% moves an entity, obviously. Declared here to avoid anonymous functions
%% being constantly re-declared.
move_entity(Pid, X, Y, Z, V, Xsize, Ysize) ->
{X2, Y2} = movement:move({X, Y}, V),
{Pid, valid_space(X2, Xsize), valid_space(Y2, Ysize), Z, V}.

% clamps space coordinates FIXME: magic numbers
%% clamps space coordinates, does wrap-around.
valid_space(C, Size) ->
case C of
C when C >= (Size / 2) ->
Expand Down
1 change: 0 additions & 1 deletion src/spacewar1_app.erl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
start(_StartType, _StartArgs) ->
Dispatch = cowboy_router:compile([
{'_', [
{"/", test_handler, []},
{"/ws", ws_handler, []},
{"/[...]", cowboy_static, [
{directory, {priv_dir, spacewar1, []}},
Expand Down
14 changes: 0 additions & 14 deletions src/test_handler.erl

This file was deleted.

10 changes: 8 additions & 2 deletions src/torps.erl
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
-module(torps).
-export([torp/1]).

%%%----------------------------------------------------------------------
%%%
%%% Each live torpedo is tracked by an instance of this module/process.
%%%
%%%----------------------------------------------------------------------

torp(Player) ->
torp(Player, 100).

Expand All @@ -17,12 +23,12 @@ torp(Player, TicksRemaining) ->
io:format("Torp killed by space~n", []),
torp(Player, 0);
{hit, Player} ->
%% this is a suicide
%% if a player hits themself with their own torpedo,
%% it's considered a suicide.
gen_server:cast(space_score, {Player, -1}),
torp(Player, 0);
{hit, WhoDidWeHit} ->
io:format("Torp hit~n", []),
%whereis(space_score) ! {Player, 1},
gen_server:cast(space_score, {Player, 1}),
torp(Player, 0);
_ ->
Expand Down
6 changes: 3 additions & 3 deletions src/ws_handler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,19 @@ websocket_handle({text, Msg}, Req, State) ->
State ! {attitude, -1};
<<_, "1", _, _>> ->
State ! {attitude, 1};
_ -> 0
_ -> Msg
end,

case Msg of
<<_, _, "1", _>> ->
State ! thrust;
_ -> 0
_ -> Msg
end,

case Msg of
<<_, _, _, "1">> ->
State ! torp;
_ -> 0
_ -> Msg
end,

{ok, Req, State};
Expand Down

0 comments on commit 1aeae75

Please sign in to comment.