How to build a game like Battleship?

  • I think with the PIN behavior is more practical, but I don't understand why you changed the point of origin. Now the sprite appears on the line rather than within the squares. It's necessary because you are using PIN?

    Because you don't need the grid anymore. But you can keep the Origin at 0,0 you just have to adjust the "Front" and "End" image points.

    Two other important issues that it's very difficult for me: the problem of overlap and the fact that the ship is out of the playing area (sea sprite).

    You have to add "rules" for where to place the ship. A way you can do it is by adding some check sprites around the game area, if the ships are overlapping those then try a new location. For the overlap you just make a Sprite and tell it to follow your mouse cursor, and then when the player press the left button you check to see if that sprite is overlapping a ship part.

    I tried to create a loop with Repeat event and not work 100%. Sometimes the ship appears overlapping other.

    You cant really use repeat, as you don't know how many times you have to repeat it. So either you have to use a ship counter, or a while loop.

    If you want to place 5 ships you make a counter like "Ship_placed = 0" and every time you successfully place a ship you add 1 to this, and every time you detect an overlap you subtract one. And then you let the event run as long "Ship_placed < 5".

    I also need to restrict the area to ensure that ships always appear on the sea sprite. Do you know how can I solve this?

    You can do that with if you place those sprites around the play area and check if the ship overlap one of those.

  • Very nice, Thanks for the suggestions about overlapping issues. I�ll create the sprite and put it around the game area to restrict it.

    I just don't understand very well the identification of the ships. I beleive that I need to spread 100 sprites on the game area for when the player clicks on one of them, check if there's a part of the ship below. In this case, it first needs to know if any item of the family is there, isn't? If confirmed, then I need to check which part of the ship is, right?

    I intend to create five different types of ships and include them in a single family. But in fact, will be different parts of ships separated. Can I relate all parties to a single ship, or a single name?

    The same issue occurs when I have to check if a ship was included on the screen to see if it is overlapping some other ship. I can check if a piece of the ship was placed. But how can I check if the entire ship was included in the game? I think the solutions is: check each piece of the ship, relating the number of pieces to a variable and check whether the variable has a value compatible with the number of pieces? Is it? I beleive that you have a better solution.

    I really want to thank you for your patience and dedication to this thread. I really appreciate this.

  • I?ll create the sprite and put it around the game area to restrict it.

    Yeah you still have to place the ship somewhat correctly when you create it.

    So System->create Ship_mid_1 on X=int(Random(500)) and Y = int(Random(500))

    This would create that ship somewhere on 0-500x, 0-500y.

    So you have specify the range, like so:

    System->create Ship_mid_1 on X=int(Random(200,500)) and Y = int(Random(200,500))

    Then the ships will be placed between 200,500x and 200,500y

    I just don't understand very well the identification of the ships. I beleive that I need to spread 100 sprites on the game area for when the player clicks on one of them, check if there's a part of the ship below.

    You don't need to add 100 sprites. What you can do is to simply add two variable to the ship.family for instant (BE ADVISED YOU ONLY NEED TO ADD THESE VARIABLES IF YOU WANT TO DO SOMETHING SPECIAL FOR EACH PART OF THE SHIP, OTHERWISE YOU DONT NEED THEM):

    Ship_number = 1

    Ship_part = "Mid"

    Then when you create the ships and lets say you know that you need 5 ships.

    The middle part of the ship is what we use to control a ship. As its the part that hold the "Front" and "End" image points.

    So it would look like this:

    1. First check if Number_of_ship_placed < than 5

    if that's the case, we need to create a ship:

    2. System->create Ship_mid_1 on X=int(Random(200,500)) and Y = int(Random(200,500))

    • Ship_mid_1.Ship_number = Number_of_ships_placed
    • Ship_mid_1.Ship_part = "Mid"

    So now you would have a ship like this:

    -o- <- middle part of the ship :)

    (Then you know that this ship is number 1 ship, and its the middle part of it)

    3. Then you spawn the rest of the ship parts.

    So first we add the front part:

    • On event Ship_mid_1 created

    Ship_mid_1 spawn new object "Ship_front_1" at imagepoint "Front"

    Ship_front_1.Ship_number = ship_mid_1.Ship_number (Now it have the same ship number as the middle part)

    Ship_front_1.ship_part = "Front" (And now you know its the front part)

    So now the ship looks like this:

    <-o-

    Then we spawn the last part exactly the same way:

    Ship_mid_1 spawn new object "Ship_end_1" at imagepoint "End"

    Ship_end_1.Ship_number = ship_mid_1.Ship_number (Now it have the same ship number as the middle part)

    Ship_end_1.ship_part = "End" (And now you know its the end part)

    And finally the ship looks like this:

    <-o-)

    Then we pin these parts to the middle part, so we only have to work with that piece when we have to manipulate it.

    Ship_front.pin to object -> Ship_mid_1

    Ship_end.pin to object -> Ship_mid_1

    And finally you change the rotation of the middle part, to add the random rotation.

    Ship_mid_1.angle = random(360)

    If you in the pin behaviour have put it to "Position and angle" the other parts will follow the middle part correctly.

    To check for hit

    1. If Crosshair is overlapping Ship.family

    Since it can overlap more than one part, you just use pick nearest as well, so it only picks 1.

    And then you can now just check for ship number and ship part if you want to do something special to these parts. Or if you just want to destroy them you can just add:

    • On event Mouse.left click object -> ship_family

    Pick nearest ship to crosshair.

    • Ship -> destroy

    Show equation somewhere on the screen.

    Here is an example of the crosshair and overlapping functionality.

    Just spawn a ship with Q again and left click on a ship.

    Battleship crosshair test

  • But when the ship has 2, 4 or 5 pieces? In these cases, I can have 3, 2 or no piece in the middle of the ship. When you have 3 or 2 middle parts, all have the points of origin "front" and "end"? And the ship with two parts?

  • But when the ship has 2, 4 or 5 pieces? In these cases, I can have 3, 2 or no piece in the middle of the ship. When you have 3 or 2 middle parts, all have the points of origin "front" and "end"? And the ship with two parts?

    You just modify each ship part so they fit. And you can freely decide which part of the ship you want to manipulate to control the ship. The size of the ship doesn't matter.

    Some examples.

    <) 2 part ship.

    (Just add an image point to the "End" part called "front" and spawn the front part to that one or the other way around, doesn't really matter)

    <--) 4 part ship.

    (You could choose the 2 part, and there you add a "Front" and a "Mid_part_2", and you spawn the second mid part to that. And in the second mid part you just add one called "End" and spawn the end to that one. Then you pin all of them to your control part, which in this case is "Mid_part_1")

    <---) 5 part ship

    (Exactly the same as a 4 part ship, you just add a "Mid_part_3" to second mid part. And in the third mid part you add the "End" part)

    Then in your code you can just make a "Ship creator" as I did in the example for each ship. And depending on which ship you want to create you use the correct "Ship creator".

    As you create the different ships in design mode, you just make sure that the image points fits what you need.

    So the "End" part used for a 2 part ship is not necessarily the same used for a 5 part ship. You could do it like that, but that's up to you to decide. You just have to modify the code accordingly, and not use the image points for some sizes ships that you would use for others.

    To explain it a bit more clear:

    If you only have 3 ship parts ("Front", "Mid", "End") you can make any size ship with these if you want. Doesn't matter whether its 4 or 100 long. The only thing is that if you want to use a 2 part ship, you have to add a front image point to the "End" part as well, which you only use for 2 part ships.

    And to the mid part you have added "Front" and "End" image points.

    Then you can in principal add whatever sprite you want to these image points. The names "Front" and "End" could just as well have been called "Snow" and "Rain" it wouldn't make any different, they are just names of the image points, that you have told construct 2 that you want them to be.

    (Just some information about why to use names: The reason its always good to name things like "image points" and "layers" for instant, is if you don't and just refer to them with there index number. Like if you look at your layers, they have an index number starting at 0, and if you add another layer it will be 1. You can add objects such as your ships to a certain layer if you want, by saying "Spawn ship on layer 0" however if you instead of using the index number use the name of the layer. like "Spawn ship on layer "Playing area". You can move these layers around as you please, and then you don't screw up things. Imagine that you use the index number 0, and suddenly figure out that it would be pretty nice if the "Water" was on its own layer below where the "Ships" are. If you do that and you don't use the name of the layer. You have to go through all your code an correct all the index numbers, because now the "Water" is actually on the layer with index 0 and the "Ships" should be on layer 1, but if you use names you can just drag the layers as you please, because the name of the layer doesn't change.....anyway just a short explanation :))

    So back on track.

    Since "Front" and "End" are just names, you can just spawn another mid part on "End" and then get the new "Mid" part to spawn the "End" part of the ship instead.

  • You `re the guy. Each post is a lesson. The best thread about a game construction that I participated so far. All very well explained.

    I will now give you a rest :). I'll digest it all and put into practice. Please do not disappear. After implementing all you said, I will return to give you a position or clarify another question, if you allow it. Thank you.

  • Sure no problem :) hope it works out for you

  • nimos100

    I'm came back (sooner than I thought).

    I've trouble with while loop. I did the following:

    numberShips = 0

    while

    numberShips <3: Create object Ship1_mid

    family is overlapping family: System subtract 1 to numberShips

    ???????????????? or

    family is overlapping margin (new sprite to restrict game area)

    The overlapping still happens.

    The other problem is with the other parts of the ship (front and end), leaving the restricted area and also overlaps

    What's wrong?

  • Try to link the capx file

  • Here is an example of how to do it.

    There are still overlapping, as this example only checks whether the mid part of the ship overlaps with the boundaries, and so you can see how its done.

    So to check for overlapping you still have to check for the other things, such as if front or end part is overlapping etc.

    Anyway I made some changes so i removed the While loop.

    And instead use a Ship_placed boolean which can be 0 for false and 1 for true. This is because there can be some problems with newly created objects. So doing it this way will remove that.

    So now it simply uses

    Number_of_ships < 3

    Then I have added a Overlap checker which will run as long as:

    Number_of_ships < 3

    Ship_placed = 0

    So when all ships have been placed Ship_placed = 1 and the overlapping checker stops.

    Secondly I have added a Identifier to the ships, based on the UID of the mid part. So each part ("Front", "End") can be selected through this and destroyed as well when an overlap is detected.

    Battleship Ship placement overlapping test

  • Nice solution, nimos100

    I found very difficult to use "while". I only had used REPEAT and FOR before.

    As you said, the ships are still overlapping others ships. I thought to include the condition "Ship_1_mid is overlapping family" in the group "Ship overlapping checker"? Anyway to use "or" and "and" together in the same conditions block?

    I had not commented, but I keep using the grid instead of creating ships in coordinates. I want that ships are included in the columns and rows. To create different angles, I'm using CHOOSE pointing angles 0/90/-90/180

  • Avoid overlapping of ships with the border sprites is simple. However, to avoid overlap of ships of other ships, divided into several parts is very complicated, mainly because I will have to create 05 different types of ships. Perhaps the hardest part of the game.

    I'll check the overlapping in "Ship_1_mid on created" event and destroy that part if overlapping is confirmed. If not, I'll create the other parts (end/front) after the "else" event.

    Sometimes 03 ships appears, but after several refreshs, one or more ships disappear sometimes.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • I found very difficult to use "while". I only had used REPEAT and FOR before.

    No worries you don't really need "while" anyway and in most cases its best to use a "for" loop instead anyway. And you can get it to work as a "while" loop as well.

    As you said, the ships are still overlapping others ships. I thought to include the condition "Ship_1_mid is overlapping family" in the group "Ship overlapping checker"? Anyway to use "or" and "and" together in the same conditions block?

    Yeah there shouldn't be any problems in modifying the code so it works for that as well. Its pretty much the same.

    What you can do, which I personally like to do, when I have to work with complicated tasks, is to write in short text what I would like to do, before I even start coding anything.

    For instant in your case it could be like this, you can just write it as comments (Q hotkey).

    1. Spawn mid part of ship at random location.

    2. Choose size of ship.

    3. Give ship a fixed rotation (0,90,180, 270)

    4. Spawn rest of the ship parts.

    5. Check that ship is within game area, and is not overlapping boundary.

    6. Check that ship is not overlapping another ship.

    Whether it should be exactly like that for you I don't know, but it kind of give you some overview/guide of what needs to be done, and you can focus on one task at the time, and make sure that it works before moving to the next.

    Avoid overlapping of ships with the border sprites is simple. However, to avoid overlap of ships of other ships, divided into several parts is very complicated, mainly because I will have to create 05 different types of ships. Perhaps the hardest part of the game.

    Actually I don't think its a lot more complicated, since you can just test:

    ship is overlapping ship

    Ship UID not equal to the UID that you are currently checking

    Then it will check all other ships, except the one you are currently checking for overlaps. It might sound complicated I agree, but if you think about it like this, if we assume that you want to check that a destroyer with a unique name of "King Paul" is not overlapping another ship:

    Check if a ship named "King Paul" is overlapping another ship, but don't check against ships that are called "King Paul".

    Then it doesn't sound that complicated, it actually sounds pretty straight forward. Since the UID of an object in C2 is unique, we can use that, its just a number rather than a name like "King Paul". :)

    If you compare it to the boundary, and we assume that we only want to check the right boundary for whatever reason:

    Check if a ship is overlapping a boundary. But the boundary must be on the right side.

    Its pretty much the same, both have two conditions. If you compare that to the actual boundary check that you use, which only have one condition:

    Check if a ship is overlapping a boundary

    Its not really all that more complicated, you just have to check each ship part, that are "linked" to the ID of the ship. Like if "King Paul" is made up of 3 parts, you have to check all ship parts, that have the name "King Paul" in the Ship_ID variable, and you can do that with a loop, like is:

    Ship_ID = "King Paul" (Will pick all ship part with that name)

    For each Ship

    [Then you do the checks]

  • Before all, thanks for the tips and come here on Sunday to help.

    I've noticed that the logical issues are very easy for you. For me, programming, even with so many facilitators as they have in Construct2, is more difficult. I know it's a matter of logic and commands are details. I think that I should invest in logic. Would you recommend something for this (book / website / etc). It has to be for beginners.

    I think (just think) that I understood your explanations and I'll try to implement them. I hope that I can still consult you.

    Thanks again.

  • I use this:

    family1 shipID = ship_1_mid.UID

    for each family1

        family1 is overlapping family1: family Destroy

                                        System Subtract 1 from Nr_of_placed

    but not work. Maybe the problem is the subevent that verify if overlap happens?

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)