Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Challenge: 2D Tank

Name: Anonymous 2010-05-14 15:43

The Challenge:
|---->Program a 2d tank application in the language of your choice that adheres to the following:

#-The tank must rotate using the left and right directional keys.
#-The tank must loosely resemble a tank.
#-The tank must move forward or backward respectively from the direction it is facing using the up and down directional keys.
#-Pressing spacebar must fire a 'shot' in the direction the tank is facing.
#-The perspective of the user must be fixed and facing down at the tank.
#-The tank, shot, and ground must each have their own color. (all shots may have the same color)


<------You have 24 hours!------>
GET TO WORK!

Name: Anonymous 2010-05-14 15:48

But /prog/ has... NO PROGRAMMERS.

Name: Anonymous 2010-05-14 15:50

Mosikasite, this is your homework?

Name: Anonymous 2010-05-14 15:51

I'm an artist.
I can paint you a smiling tank crushing little children in Africa.

Name: Anonymous 2010-05-14 15:56

OP this is too hard.

Name: Anonymous 2010-05-14 15:58

MAKE US PROGRAM SOMETHING EASY, LIKE A BUTTSORTER.

Name: Anonymous 2010-05-14 16:00

>>6
I am 12 and what is a buttsorter?

Name: Anonymous 2010-05-14 16:38

>>3
You're an eleven, aren't you
Western romanizers use shi.

Name: Anonymous 2010-05-14 16:47

this almost looks like it would be fun to program, until realizing that graphics are annoying and CLI interfaces are so much better

Name: Anonymous 2010-05-14 17:08

>>9
That didn't stop roguelikes!

Name: Anonymous 2010-05-14 17:14

do your own tank homework

Name: Anonymous 2010-05-14 17:24

>>11
Everyone in /prog/ has been assigned tank homework, but nobody will be doing it.

Name: Anonymous 2010-05-14 17:38

sounds cool op. if I didn't have to much homework I would do this.

Name: Anonymous 2010-05-14 17:46

>>9
For a moment there you had me thinking that someone would consider something other than curses for this problem.

Name: Anonymous 2010-05-14 17:49

>>12
ah, this reminds me of my school time.
it was terrible!
needless to say i was the geekiest kid in school.

Name: Anonymous 2010-05-14 18:04

>>1
I finished early, what do I get?

/* gcc -o susstank -ansi susstank.c -lm `allegro-config --libs` */

/* Copyright (c) 2010 Xarn
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include <stdio.h>
#include <math.h>
#include <allegro.h>

#define WIDTH  729
#define HEIGHT 729

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

int main(void)
{
    int tx = WIDTH / 2, ty = HEIGHT / 2, mx = tx, my = ty, firing = 0;
    fixed tangle = 0, mangle = 0;
    double rtangle = 0, rmangle = 0;
    BITMAP *background, *tank, *miss, *buffa;

    allegro_init();
    install_keyboard();
    install_timer();

    set_color_depth(32);
    if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, WIDTH, HEIGHT, 0, 0) != 0) {
        fprintf(stderr, "Couldn't initialise Allegro!\n");
        return 1;
    }
    set_window_title("SUSSTANK");

    buffa = create_bitmap(WIDTH, HEIGHT);
    background = load_pcx("back.pcx", NULL);
    tank = load_pcx("tank.pcx", NULL);
    miss = load_pcx("miss.pcx", NULL);
    if (!background || !tank || !miss) {
        fprintf(stderr, "Couldn't load images!\n");
        return 2;
    }

    for (;;) {
        int k;

        blit(background, buffa, 0, 0, 0, 0, WIDTH, HEIGHT);
        if (firing)
            pivot_sprite(buffa, miss, mx, my, miss->w / 2, miss->h / 2, mangle);
        pivot_sprite(buffa, tank, tx, ty, tank->w / 2, tank->h / 2, tangle);
        blit(buffa, screen, 0, 0, 0, 0, WIDTH, HEIGHT);

        if (keypressed()) {
            k = readkey();

            if ((k & 0xff) == 'q')
                break;

            switch (k >> 8) {
            case KEY_SPACE:
                if (!firing) {
                    mx = tx;
                    my = ty;
                    mangle = tangle;
                    rmangle = rtangle;
                    firing = 1;
                }
                break;
            case KEY_LEFT:
                tangle -= 8 << 16;
                rtangle = (tangle >> 16) * M_PI / 128;
                break;
            case KEY_RIGHT:
                tangle += 8 << 16;
                rtangle = (tangle >> 16) * M_PI / 128;
                break;
            case KEY_UP:
                tx += 8 * cos(rtangle);
                ty += 8 * sin(rtangle);
                break;
            case KEY_DOWN:
                tx -= 8 * cos(rtangle);
                ty -= 8 * sin(rtangle);
                break;
            }
        }

        if (firing) {
            mx += 20 * cos(rmangle);
            my += 20 * sin(rmangle);
            if (mx < -50 || mx > WIDTH + 50 || my < -50 || my > HEIGHT + 50)
                firing = 0;
        }

        rest(20);
    }

    return 0;
} END_OF_MAIN()


Get images from http://cairnarvon.rotahall.org/susstank/

Name: Anonymous 2010-05-14 18:26

Disclaimer: this code has many examples of "bad practices" because I was 100% focused on minimize coding time while  meeting the requirements

import java.awt.*;
import java.applet.*;
import java.util.*;
import java.awt.event.*;
import java.awt.image.*;

public class a extends Applet implements Runnable,KeyListener{
    double x,y;
    double r,sdx,sdy;
    boolean left,right,down,up;
    double sx=-5,sy=-5;
    int TANK_SIZE=20;
    BufferedImage buf;   
    public void init(){
        x=getWidth()/2;
        y=getHeight()/2;
        addKeyListener(this);
        buf=new BufferedImage(getWidth(),getHeight(),BufferedImage.TYPE_3BYTE_BGR);
        new Thread(this).start();
    }
    public void update(Graphics g){
        paint(buf.getGraphics());
        g.drawImage(buf, 0,0,null);
    }
    public void paint(Graphics g){
        int[] xpoints=new int[8];
        int[] ypoints=new int[8];
        for(int i=0;i<4;i++){
            xpoints[i]=(int)(x+TANK_SIZE*Math.cos(r+i*Math.PI/2));
            ypoints[i]=(int)(y+TANK_SIZE*Math.sin(r+i*Math.PI/2));           
        }
        xpoints[4]=(4*xpoints[0]+5*xpoints[3])/9;
        ypoints[4]=(4*ypoints[0]+5*ypoints[3])/9;
        xpoints[5]=(int)(x+1.5*TANK_SIZE*Math.cos(r-3*Math.PI/11));
        ypoints[5]=(int)(y+1.5*TANK_SIZE*Math.sin(r-3*Math.PI/11));   
        xpoints[6]=(int)(x+1.5*TANK_SIZE*Math.cos(r-3*Math.PI/13));
        ypoints[6]=(int)(y+1.5*TANK_SIZE*Math.sin(r-3*Math.PI/13));   
        xpoints[7]=(5*xpoints[0]+4*xpoints[3])/9;
        ypoints[7]=(5*ypoints[0]+4*ypoints[3])/9;
        g.setColor(Color.gray);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(Color.green);
        g.fillPolygon(xpoints,ypoints,8);
        if(left)
            r-=.1;
        if(right)
            r+=.1;
        double dx=Math.cos(r-Math.PI/4);
        double dy=Math.sin(r-Math.PI/4);
        if(up){
            x+=dx*10;
            y+=dy*10;
        }
        if(down){
            x-=dx*10;
            y-=dy*10;
        }
        g.setColor(Color.yellow);
        if(sx!=-5&&sy!=-5){
            sx+=sdx;
            sy+=sdy;
        }
        if(sx<-3||sx>getWidth()||sy<-3||sy>getWidth()){
            sx=-5;
            sy=-5;
        }
        g.fillOval((int)sx-1, (int)sy-1,3, 3);
    }
    public void run() {       
        while(true){
            Graphics g=getGraphics();
            if(g!=null)
            update(getGraphics());
            try{
                Thread.sleep(30);
            }catch(Exception e){}           
        }
    }
    public void keyPressed(KeyEvent e) {   
        switch(e.getKeyCode()){
        case KeyEvent.VK_UP:
            up=true;
            break;
        case KeyEvent.VK_DOWN:
            down=true;
            break;
        case KeyEvent.VK_LEFT:
            left=true;
            break;
        case KeyEvent.VK_RIGHT:
            right=true;
            break;   
        case KeyEvent.VK_SPACE:
            if(sx==-5&&sy==-5){
                sx=x;
                sy=y;
                sdx=Math.cos(r-Math.PI/4)*20;
                sdy=Math.sin(r-Math.PI/4)*20;
            }
            break;
        }
    }
    public void keyReleased(KeyEvent e) {
        switch(e.getKeyCode()){
        case KeyEvent.VK_UP:
            up=false;
            break;
        case KeyEvent.VK_DOWN:
            down=false;
            break;
        case KeyEvent.VK_LEFT:
            left=false;
            break;
        case KeyEvent.VK_RIGHT:
            right=false;
            break;           
        }
    }
    public void keyTyped(KeyEvent e){}   
}

Name: Anonymous 2010-05-14 18:30

>>16
Anyone else get the feeling that Xarn sets these challenges himself, just so that he can be the first to respond

Name: Anonymous 2010-05-14 18:33

>>16
disqualified since suss-mans head does not vaguely resemble a tank. I win.


I didn't know allegro was so clean, nice.

Name: Anonymous 2010-05-14 18:45

>>19
CLEAN MY ANUS

Name: Anonymous 2010-05-14 19:02

>>19
The Sussman's head is actually the missile. The tank is the /prog/snake head.

Name: Anonymous 2010-05-14 19:21

>>17
You know your language sucks when the C version of your program manages to be shorter and more readable. Friends don't let friends use Java.

Name: Anonymous 2010-05-14 19:53

>>16
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

This is unnecessary if you define _BSD_SOURCE or _XOPEN_SOURCE=500. The math.h man page doesn't tell you this for some reason, but M_PI isn't part of ANSI C, so compiling with -ansi undefines it (along with a bunch of other constants).
I initially thought glibc was being retarded, but it turns out it was just poor documentation.

Name: Anonymous 2010-05-14 20:05

>>22
It wasn't written for shortness or readability thus the disclaimer, 100% code time. Also the ugliest part is the tank drawing which the C version sidesteps by using images.

Name: Anonymous 2010-05-14 22:02

>>19
Crap like END_OF_MAIN() is what you consider "clean"? Sorry dude.

Name: Anonymous 2010-05-14 22:14

>>25

compared to the boilerplate needed for win32, opengl or directx to do the same? yes, no contest

Name: Anonymous 2010-05-14 22:17

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

static class Program
{
    static void Main(string[] args)
    {
        using (TankGame game = new TankGame()) game.Run();
    }
}

public class Entity
{
    public Texture2D Texture;
    public Vector2 Location;
    public float Facing;
    public float Velocity;

    public Vector2 Origin { get { return new Vector2(this.Width / 2, this.Height / 2); } }
    public int Height { get { return Texture.Height; } }
    public int Width { get { return Texture.Width; } }

    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(this.Texture, this.Location, null, Color.White, this.Facing, this.Origin, 1.0f, SpriteEffects.None, 0.0f);
    }

    public void Update()
    {
        Location.X += this.Velocity * (float)Math.Cos(Facing);
        Location.Y += this.Velocity * (float)Math.Sin(Facing);
    }

    public Entity(Texture2D Texture, Vector2 Location, float Facing, float Velocity)
    {
        this.Texture = Texture;
        this.Location = Location;
        this.Facing = Facing;
        this.Velocity = Velocity;
    }
}

public class TankGame : Microsoft.Xna.Framework.Game
{
    const int screenWidth = 420;
    const int screenHeight = 320;

    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;

    Texture2D tankTexture;
    Texture2D shotTexture;

    Entity tank;
    List<Entity> shots;

    public TankGame()
    {
        graphics = new GraphicsDeviceManager(this);
        this.graphics.PreferredBackBufferHeight = screenHeight;
        this.graphics.PreferredBackBufferWidth = screenWidth;
        Content.RootDirectory = "Content";
    }

    protected override void LoadContent()
    {
        this.spriteBatch = new SpriteBatch(GraphicsDevice);
        this.tankTexture = base.Content.Load<Texture2D>("tank");
        this.shotTexture = base.Content.Load<Texture2D>("shot");

        this.tank = new Entity(tankTexture, new Vector2(screenWidth / 2, screenHeight / 2), 0, 0);
        this.shots = new List<Entity>();
    }

    protected override void Update(GameTime gameTime)
    {
        KeyboardState keyboard = Keyboard.GetState();

        if (keyboard.IsKeyDown(Keys.Space))
            this.shots.Add(new Entity(this.shotTexture, this.tank.Location, this.tank.Facing, 16f));
        if (keyboard.IsKeyDown(Keys.Left))
            this.tank.Facing += (float)Math.PI / 64;
        if (keyboard.IsKeyDown(Keys.Right))
            this.tank.Facing -= (float)Math.PI / 64;
       
        if (keyboard.IsKeyDown(Keys.Up))
            this.tank.Velocity = 4.0f;
        else if (keyboard.IsKeyDown(Keys.Down))
            this.tank.Velocity = -4.0f;
        else
            this.tank.Velocity = 0f;

        this.tank.Update();
        foreach (Entity shot in shots) shot.Update();

        base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.DarkGreen);

        spriteBatch.Begin();
        this.tank.Draw(this.spriteBatch);
        foreach (Entity shot in shots) shot.Draw(this.spriteBatch);
        spriteBatch.End();

        base.Draw(gameTime);
    }
}

Name: Anonymous 2010-05-14 22:28

>>25
I can only assume you've never used a game programming or graphic library yourself.
You can even leave out END_OF_MAIN(), if you like. It's only there for the retarded platforms. It saves you the effort of having to write a WinMain by hand.

Name: Anonymous 2010-05-14 22:42

>>28
SDL doesn't have to put up with that shit.

Name: Anonymous 2010-05-14 22:46

>>29
But with SDL you're coding with shit.

Name: Anonymous 2010-05-14 23:22

>>30
So why not do the same WinMain hack in Allegro that SDL is using? All they do is #define main to SDLmain or something, and link the "real" main in the library itself.

Name: Anonymous 2010-05-14 23:22

>>25
The people making fun of you are right to do so, but I just wanted to add that END_OF_MAIN() looks very natural in combination with <void.h>

Name: Anonymous 2010-05-15 0:35

a dozen digits of precision for pi

IHBT

Name: Anonymous 2010-05-15 0:38

>>33
Are you one of those "pi = 3" religious nutjobs?

Name: Anonymous 2010-05-15 0:46

>>33
Copy/pasted from math.h.

Name: Anonymous 2010-05-15 1:13

>>33-35
#define M_PI (4*atan(1))

Name: Anonymous 2010-05-15 1:47

>>33
How many is enough? Engineers and physicists usually claim to need about 3-5. I need about 7. Almost no one needs as much as 12, but since it's a constant: why not?

>>36
YOU MENA HASKAL

Name: Anonymous 2010-05-15 1:58

Name: Anonymous 2010-05-15 2:11

I am an Enterprize Java Developer


import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.lang.Math;


public class tankApp extends java.applet.Applet implements MouseListener, KeyListener {

    private static final long serialVersionUID = 1L;
    boolean start = false;
    double xpos = 0;
    double ypos = 0;
   
    final int distance = 200;
    double counter = 0;
    burret[] shots = new burret[3];
   
    boolean mouseEntered;
    boolean up = false;
    boolean down = false;
    boolean left = false;
    boolean right = false;
   
    Graphics bufferGraphics;
    Image offscreen;
    Image offscreen2;
    Dimension dim;
    Graphics2D g2;
   
    AffineTransform aT;
    AffineTransform rotate;
    Rectangle2D rect = new Rectangle2D.Float(15, 15, 10, 10);
       
    public void init()  {
        int i;
        setBackground(Color.white);
        setSize(640, 480);
        dim = getSize(); 
        offscreen = createImage(dim.width,dim.height);
        bufferGraphics = offscreen.getGraphics();
        offscreen2 = createImage(40,40);
        for(i = 0; i < 3; i++)
        {
            shots[i] = new burret(0, 0, 0);
        }
        g2 = (Graphics2D) offscreen2.getGraphics();
       
        xpos = 0;
        ypos = 0;
               
            addMouseListener(this);
            addKeyListener(this);
            repaint();
    }
       
    public void paint( Graphics g ) {
        int i;
        if(getSize().height != dim.height || getSize().width != dim.width)
        {
            System.out.println(dim + " " + getSize());
            dim = getSize(); 
            offscreen = createImage(dim.width,dim.height);
            offscreen2 = createImage(40,40);
           
            g2 = (Graphics2D) offscreen2.getGraphics();
           
        }
       
        bufferGraphics.clearRect(0,0,dim.width,dim.height);
        g2.clearRect(0, 0, 40, 40);
        g2.setColor(new Color(255, 0, 0, 10));
        g2.fillRect(0,0,40,40);
        g2.setColor(Color.black);
        bufferGraphics.setColor(Color.BLUE);
       
        if(!start)
        {
            bufferGraphics.drawString("Click to start!", dim.width/2 - 100, dim.height/2 - 20);
            bufferGraphics.setColor(Color.white);
        }
       
        aT = g2.getTransform();
        rotate = AffineTransform.getRotateInstance(counter,20,20);
        
        g2.transform(rotate);
        g2.draw(rect);
        g2.drawLine(30, 20, 20, 20);
        g2.setTransform(aT);
        bufferGraphics.drawString("Angle: " + Math.round(180*counter/Math.PI), 5, dim.height - 20);
        bufferGraphics.drawImage(offscreen2,(int)xpos, (int)ypos,this);
      
        for(i=0; i < 3; i++)
       {
           if(shots[i].active == true)
               bufferGraphics.drawRect((int)shots[i].xPos, (int)shots[i].yPos, 5, 5);
       }
      
       g.drawImage(offscreen,0,0,this);
       cont();
    } 
       
   
    private void cont() {
        int i;
        if(xpos > 0 - 20 && ypos > 0 - 20 && ypos < dim.height && xpos < dim.width)
        {
            for(i = 0; i < 3; i++)
            {
                if(shots[i].active == true)
                {
                    shots[i].travel();
                    if(shots[i].timeCounter > distance && shots[i].active == true)
                        shots[i].active = false;
                }
            }
           
            if(up)
            {
                xpos = xpos + Math.cos(counter);
                ypos = ypos + Math.sin(counter);
            }
            if(down)
            {
                xpos = xpos - Math.cos(counter);
                ypos = ypos - Math.sin(counter);
            }
           
            if(right)
            {
                counter = counter + Math.PI/180;
                if(counter >= 2*Math.PI)
                    counter = counter - 2*Math.PI;
               
            }
            if(left)
            {
                counter = counter - Math.PI/180;
                if(counter < 0)
                    counter = counter + 2*Math.PI;
            }
        }
        else
        {
            xpos = dim.width / 2;
            ypos = dim.height / 2;
        }
        repaint();
    }


    public void mouseClicked (MouseEvent me) {  
       
    }
    public void mousePressed (MouseEvent me) {
       
        start = true;
        repaint();
    }

      public void mouseReleased (MouseEvent me) {
         
      }

       public void mouseEntered (MouseEvent me) {
       mouseEntered = true;
       repaint();
      }

       public void mouseExited (MouseEvent me) {
      
       mouseEntered = false;
       repaint();
      } 
      
      public void update(Graphics g)
      {
       paint(g);
      }

    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        //System.out.println("test ");
          if ( key == KeyEvent.VK_UP )
              up = true;
          if ( key == KeyEvent.VK_LEFT )
              left = true;
          if ( key == KeyEvent.VK_DOWN )
              down = true;
          if ( key == KeyEvent.VK_RIGHT )
              right = true;
             repaint();
             e.consume();
       
    }
   
    public void keyReleased(KeyEvent e) {
        int key = e.getKeyCode();
        int i;
       
          if ( key == KeyEvent.VK_UP )
              up = false;
          if ( key == KeyEvent.VK_LEFT )
              left = false;
          if ( key == KeyEvent.VK_DOWN )
              down = false;
          if ( key == KeyEvent.VK_RIGHT )
              right = false;
          if ( key == KeyEvent.VK_SPACE)
          {
              for(i = 0; i < 3; i++)
              {     
                  if(shots[i].active == false)
                  {
                      shots[i] = new burret(xpos, ypos, counter);
                      shots[i].active = true;
                      i = 3;
                  }
              }
             
          }
       
    }

    public void keyTyped(KeyEvent e) {
    }
}

public class burret {
   
    double xPos;
    double yPos;
    double angle;
    double xComp;
    double yComp;
    double timeCounter;
    boolean active;
   
    public burret(double x, double y, double a)
    {
        xPos = x + 20 - 2.5;
        yPos = y + 20 - 2.5;
        xComp = Math.cos(a);
        yComp = Math.sin(a);
        active = false;
    }
   
    public void travel()
    {
        xPos = xPos + xComp*2;
        yPos = yPos + yComp*2;
        timeCounter++;
    }
   
}

Name: Anonymous 2010-05-15 2:13

>>38
U MENA QUOTE FAILURE

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List