Adding bombs to the demo app

This post is about implementing bombs to the demo app. David Waller thought it would help me grasp the concept and structure of Redux better. I think it did. At least I had fun bombing the shit out of superman (Batman always wins when I play).

To start with the buttons needed to be bigger and get more space so in css/style.css I changed the code to this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
.battler {
    float: left;
    width: 125px;
    height: 205px;
    margin: 0.5em;
    border: 1px solid black;
    padding: 0.5em;
}

.battler button {
    width: 120px;
    text-align: left;
}

.battler button:nth-of-type(2n+1) {
    margin-bottom: 2px;
}

.battler button:nth-of-type(2n) {
    margin-bottom: 10px;
}

Next up I went to src/components/battler.js (or, I started there and changed the CSS along the way but hey this work flow sounds more professional) and added the property bomb. I also added buttons for bombing and controls:

propTypes: {
    // ... //
    bomb: ptypes.func.isRequired
    // ... //
},
return  <div>
                    <button key={opp} onClick={p.kill.bind(this,opp)}>{"Shoot "+opp}</button>
                    <button key={opp + "_bomb"} onClick={p.bomb.bind(this,opp)}>{"Bomb "+opp}</button>
                </div>;
var controls = {
    // ... //
    [C.BOMBING]: "sending bombs...",
    // ... //
}[p.doing[name]];

That code gave me an error to checkout src/components/battlers.jsso I did that. I only had to add props and a functions so nothing to see there, it's more or less the same as above. Next error pointed me to src/components/home.js and once there it was the same old story again. Except that I also had to map the prop to a dispatch:

var mapDispatchToProps = function(dispatch){
    return {
        bomb: function(killer,victim){ dispatch(actions.bombAt(killer,victim)); },
        // ... //
    };
};

I almost forgot! We have to add some stuff in src/constants.js as well!

module.exports = {
    // ACTION TYPES
    BOMB_AT: "BOMB_AT",
    END_BOMB: "END_BOMB",
    // ... //

    // HERO STATUSES
    BOMBING: "BOMBING",
    // ... //
};

Puh, saved my ass there! Anyway... Where almost done now! Let us add an action to src/actions.js so that we can get in contact to our inner feelings (a.k.a. reducers):

module.exports = {
  // ... //
  bombAt: function(killer,victim){
    // Another async action using the Redux-thunk syntax
    return function(dispatch,getState){
        dispatch({type:constants.BOMB_AT,killer:killer,victim:victim});
        setTimeout(function(){
            dispatch({type:constants.END_BOMB,killer:killer,victim:victim});
        }, 2000);
    };
  }
};

As you can see, it's almost identical with aimAt. The idea is that we drop the bombs and then after a while the arrive to the victim and explodes. Good luck ducking that!

Now we have finaly arrived to the good parts, the logic! In our reducer src\reducers\battlefield.js we add two cases, one for sending the bombs and one for detonating the bombs!

case C.BOMB_AT:
    newstate.doing[action.killer] = C.BOMBING;
    newstate.log.push(action.killer+" sends bombs to "+action.victim+"!");
    return newstate;
case C.END_BOMB:
    newstate.doing[action.victim] = C.DEAD;
    if (newstate.doing[action.killer] != C.DEAD) {
        newstate.doing[action.killer] = C.WAITING;
        newstate.log.push(action.killer+" celebrate the death of "+action.victim+"!");
    }
    else
        newstate.log.push(action.killer+" died before he could celebrate the death of "+action.victim+".");
    return newstate;

As you can see the killer dosen't even have to be alive once the bombs are on the go! Very effective! If you want you can check out the code here or why not try to bomb some superheros here.

Yours sincerely,
Oskar Klintrot


Tune of the day (pretty crapy but fits the whole bombing theme):