Jump to content

Design1online

Game Owner
  • Posts

    139
  • Joined

  • Last visited

  • Days Won

    11

Posts posted by Design1online

  1. I'm looking to hire someone to write PHPUnit tests for my pet game framework to increase my code coverage. I'm paying $10USD per function that's completely covered. I have 241 of 966 functions already covered which means I have 725 more to go so that's potentially $7,250 if you want to go all out on them. I will pay weekly or bi-weekly through PayPal, whichever you prefer. You must be familiar with php, OOP and have written tests using PHPUnit before. If you do more than $400 worth of work and are a US citizen you must also be able to complete a 1099 for tax purposes. Experience with composer is a plus.

    Sample of the code base

    Screen-Shot-2016-05-09-at-2_55.53-PM-1-856x1024.thumb.png.c461fbd323ddb28f8a1fabebae23c6da.png

    Screen-Shot-2016-05-09-at-2_57.15-PM-1-1024x966.thumb.png.1ce109f683b69d46e45a8de1345dc3cf.png

    Screen-Shot-2016-05-09-at-3_05.19-PM-1.thumb.png.4c030aac809f1b48a5c96cf37f745a1b.png

    Sample Documentation (will help when writing tests)

    Screen-Shot-2016-05-17-at-5_25.24-PM.thumb.png.9fd560c597d765c662bb6f53ce0ca341.png

    Sample unit test

    Screen-Shot-2015-11-14-at-9_52.23-PM-895x1024.thumb.png.75e57047467763c3e0a644a9913961b8.png

  2. I think the game should be functionally complete before you open it to an extensive member base. If you want to do an alpha phase I would make it extremely limited (say 10-20 people). In my experience opening a game that isn't functionally complete just leads to complaining from members who were expecting more than they might initially have access to. That being said, I think it's okay to open a beta phase with the game functionality being complete but potentially some initial bugs to work out because you didn't account for them in your testing -- but again the game should be functionally complete.

    That's just my $0.02 from my past experiences. I think having a good initial reaction when you first play a game is worth it's weight in gold rather than a buggy or super glitchy game play with nothing functional.

  3. I started down that route with Whoa-Horsie and you have to get really good at doing regex within text blocks. One of the problems is that if you have large text blocks it starts triggering performance problems because the number of regex searches you're doing requires a lot of CPU power. Eventually what I settled on was letting the user do /action where the action is what they want to do (kick, bite, escape, etc) and then write their text. From there look for keywords relevant to that specific action and it will cut down on the churn of your regex searches.

    Also, that path still got so big that I ended up converting the game to a full blow MMORPG that I've spent tens of thousands of dollars on over the years and it's still not done. Haha, just something to keep in mind when you start going that route.

  4. 59a48cf823939_alieninvasion_screenshot(1).png.a2e7d1466397eef52ad4e4f1e69773f4.pngThis is a little side project I did that I would like to share. It’s forked from another project I found on gitHub and liked it so much I decided to spend some time adding new features to brush up on my HTML5 skills. It uses the Canvas and Audio with JS to create multiple levels and bosses and power ups and different types of enemies and fire power. There’s plenty in the code base for you to take it and make it your own or continue to improve upon it. 

    Click the Remix button to fork it and view the source on Thimble.

     

     

     

     

    Here’s a video of the game if you’re too lazy to try it out yourself:

     
    • Like 1
  5. 59a48b8dac706_ScreenShot2017-08-28at5_28_49PM.thumb.png.89ed07ff335d688292bf1f1f54c3dd6a.png

    This is a simple HTML5 version of the classic game of pong. Play against the computer for as many levels as you can. The computer gets faster and more competitive the higher the level gets. The game can easily be customized to grow/shrink the paddles and the computer’s difficulty if you’re looking for a challenge after you’ve finished putting the tutorial together. You’ll need a current version of a browser (Chrome, Firefox) that supports HTML5 in order to complete this tutorial. Enjoy!

    Try the working version and Fork on Plunker

    Create the HTML File

    The beauty of html5 is that you can program it using javascript. This makes your html file small and super simple. All we need to do is create a canvas for the game and then include the javascript file:

    <html>
    <canvas id="battlePong"></canvas>
    < script type="text/javascript" src="battlePong.js"></script>
    </html>

    Create the Javascript File

    /**
    * File: BattlePong.js
    * Purpose: HTML5 pong game
    * Author: Design1Online.com, LLC <[email protected]>
    * Created: 6/7/2016
    **/
    
    //global game variables
    var game = {
     debug: true,
     canvas: null,
     canvasContext: null,
     frameRate: 1000,
     framesPerSecond: 30,
     fonts: {
     header: '30px Arial',
     regular: '15px Arial'
     },
     colors: {
     net: 'gray',
     background: 'black',
     header: 'red',
     text: 'white'
     },
     screens: {
     winner: false,
     startGame: true,
     levelUp: false,
     continue: false
     },
     ball: {
     x: 50,
     y: 50,
     speedX: 10,
     speedY: 4,
     threshold: 35,
     radius: 10,
     color: 'blue'
     },
     level: 1,
     pointsPerLevel: 3,
     player: {
     score: 0,
     lives: 5,
     paddle: {
     y: 250,
     thickness: 10,
     height: 100,
     color: 'green'
     }
     },
     computer: {
     score: 0,
     paddle: {
     y: 250,
     thickness: 10,
     height: 100,
     speed: 6,
     color: 'red'
     }
     }
    };
    
    /**
    * Start the game when the window loads
    **/
    window.onload = function() {
    
     //init the canvas
     game.canvas = document.getElementById('battlePong');
    
     //adjust canvas to window size
     game.canvas.width = window.innerWidth - game.computer.paddle.thickness;
     game.canvas.height = window.innerHeight;
    
     //create the context
     game.canvasContext = game.canvas.getContext('2d');
    
     //add event listeners
     game.canvas.addEventListener('mousedown', mouseClickHandler);
     game.canvas.addEventListener('mousemove', mouseMoveHandler);
    
     //start buffering the screen
     setInterval(function() { buffer(); }, game.frameRate / game.framesPerSecond);
    };
    
    /**
    * Figure out the player's mouse position
    **/
    function mouseMoveHandler(e) {
     var mousePos = mousePosition(e);
     game.player.paddle.y = mousePos.y - (game.player.paddle.height / 2);
    }
    
    /**
    * Return the x,y coordinates of the mouse in
    * relation to the screen
    **/
    function mousePosition(e) {
     var rect = game.canvas.getBoundingClientRect();
     var root = document.documentElement;
    
     return {
     x: e.clientX - rect.left - root.scrollLeft,
     y: e.clientY - rect.top - root.scrollTop
     };
    }
    
    /**
    * Handle mouse clicks
    **/
    function mouseClickHandler(e) {
    
     if (game.debug) {
     console.log('mouseClickHandler()');
     }
    
     if (game.screens.startGame) {
    
     if (game.debug) {
     console.log('Removing start screen');
     }
    
     game.screens.startGame = false;
     }
     else if (game.screens.continue) {
    
     if (game.debug) {
     console.log('Removing start screen');
     }
    
     game.screens.continue = false;
     }
     else if (game.screens.levelUp) {
    
     if (game.debug) {
     console.log('Removing level up screen');
     }
    
     game.screens.levelUp = false;
     }
     else if (game.screens.winner) {
    
     resetGame();
    
     if (game.debug) {
     console.log('Removing winner screen, showing start screen');
     }
    
     game.player.score = 0;
     game.computer.score = 0;
     game.screens.winner = false;
     game.screens.startGame = true;
     }
    }
    
    /**
    * Start the game
    **/
    function startGame() {
    
     if (game.debug) {
     console.log('Starting game...');
     }
    
     if (game.player.lives <= 0) {
     game.screens.winner = true;
     }
    
     game.ball.speedX = -game.ball.speedX;
     game.ball.x = game.canvas.width / 2;
     game.ball.y = game.canvas.height / 2;
    }
    
    /**
    * Move the ball and the computer mouse paddle
    **/
    function move() {
    
     var deltaY = 0;
    
     //move computer paddle
     var center = game.computer.paddle.y + (game.computer.paddle.height / 2);
    
     if (center < game.ball.y - game.ball.threshold) {
     game.computer.paddle.y = game.computer.paddle.y + game.computer.paddle.speed;
     } else if (center > game.ball.y + game.ball.threshold) {
     game.computer.paddle.y = game.computer.paddle.y - game.computer.paddle.speed;
     }
    
     //move ball
     game.ball.x = game.ball.x + game.ball.speedX;
     game.ball.y = game.ball.y + game.ball.speedY;
    
     //check for paddle collisions
     hitCollision();
    
     if (game.ball.y < 0) {
     if (game.debug) {
     console.log('Inverting ball Y speed 1');
     }
    
     game.ball.speedY = -game.ball.speedY;
     }
     if (game.ball.y > game.canvas.height) {
    
     if (game.debug) {
     console.log('Inverting ball Y speed 2');
     }
    
     game.ball.speedY = -game.ball.speedY;
     }
    }
    
    /**
    * Check for ball/paddle collisions
    **/
    function hitCollision()
    {
     //player paddle check
     if (game.ball.x <= 0) {
    
     if (game.debug) {
     console.log('player paddle collision check');
     console.log('ball', game.ball);
     console.log('player paddle', game.player.paddle);
     console.log(
     'hit or miss',
     game.ball.y > game.player.paddle.y,
     game.ball.y < (game.player.paddle.y + game.player.paddle.height + game.ball.radius)
     );
     }
    
     if (game.ball.y > (game.player.paddle.y) &&
     game.ball.y < (game.player.paddle.y + game.player.paddle.height + game.ball.radius)
     ) {
     game.ball.speedX = -game.ball.speedX;
    
     deltaY = game.ball.y - (game.player.paddle.y + game.player.paddle.height / 2);
     game.ball.speedY = deltaY * 0.35;
     } else {
     game.computer.score++;
     game.player.lives--;
     game.screens.continue = true;
     startGame();
     }
     }
    
     //computer paddle check
     if (game.ball.x >= game.canvas.width) {
    
     if (game.debug) {
     console.log('player paddle collision check');
     console.log('ball', game.ball);
     console.log('player paddle', game.computer.paddle);
     console.log(
     'hit or miss',
     game.ball.y > game.computer.paddle.y,
     game.ball.y < (game.computer.paddle.y + game.computer.paddle.height + game.ball.height)
     );
     }
    
     if (game.ball.y > (game.computer.paddle.y) &&
     game.ball.y < (game.computer.paddle.y + game.computer.paddle.height + game.ball.radius)
     ) {
     game.ball.speedX = -game.ball.speedX;
    
     deltaY = game.ball.y - (game.computer.paddle.y + game.computer.paddle.height / 2);
     game.ball.speedY = deltaY * 0.35;
     } else {
     game.player.score++; //increase score
    
     //level up
     if (game.player.score > 0 && game.player.score % game.pointsPerLevel === 0) {
     game.player.lives++; //get another life
     game.level++; //level up
     game.computer.paddle.speed += 1.3; //increase computer paddle speed
     game.screens.levelUp = true;
     } else {
     game.screens.continue = true;
     }
    
     startGame();
     }
     }
    }
    
    /**
    * Draw the game board
    **/
    function drawBoard() {
    
     //draw the net
     for (var i = 0; i < game.canvas.height; i += 10) {
     drawRectangle(game.canvas.width / 2 - 1, i, 2, 1, game.colors.net);
     }
    
     //draw the score text
     var offset = 100;
    
     //set the header text
     var header = "BattlePong!";
     game.canvasContext.fillStyle = game.colors.header;
     game.canvasContext.font = game.fonts.header;
     game.canvasContext.fillText(header, offset, 30);
    
     //set the colors and font style
     game.canvasContext.fillStyle = game.colors.net;
     game.canvasContext.font = game.fonts.regular;
    
     //set the score text
     var score = "Score: " + game.player.score;
     game.canvasContext.font = game.fonts.text;
     var scoreSize = game.canvasContext.measureText(score);
     game.canvasContext.fillText(score, offset + 5, 50);
    
     //set the lives text
     var lives = "Lives: " + game.player.lives;
     var livesSize = game.canvasContext.measureText(lives);
     game.canvasContext.fillText(lives, offset + scoreSize.width + 25, 50);
    
     //set the copyright text
     var copyright = "Games by design1online.com, LLC";
     var copyrightSize = game.canvasContext.measureText(copyright);
     game.canvasContext.fillText(copyright, game.canvas.width - copyrightSize.width - offset/4, game.canvas.height - offset/4);
    
     //player paddle
     drawRectangle(
     0,
     game.player.paddle.y,
     game.player.paddle.thickness,
     game.player.paddle.height,
     game.player.paddle.color
     );
    
     //computer paddle
     drawRectangle(
     game.canvas.width - game.computer.paddle.thickness,
     game.computer.paddle.y,
     game.computer.paddle.thickness,
     game.computer.paddle.height,
     game.computer.paddle.color
     );
    
     //ball
     drawBall(game.ball.x, game.ball.y, game.ball.radius, game.ball.color);
    }
    
    /**
    * Draw the ball
    **/
    function drawBall(centerX, centerY, radius, color) {
     game.canvasContext.fillStyle = color;
     game.canvasContext.beginPath();
     game.canvasContext.arc(centerX, centerY, radius, 0, Math.PI * 2, true);
     game.canvasContext.fill();
    }
    
    /**
    * Draw paddle
    **/
    function drawRectangle(leftX, topY, width, height, color) {
     game.canvasContext.fillStyle = color;
     game.canvasContext.fillRect(leftX, topY, width, height);
    }
    
    /**
    * Reset for a new game
    **/
    function resetGame()
    {
    
     if (game.debug) {
     console.log('Resetting game...');
     }
    
     game.level = 1;
     game.computer.paddle.speed = 6;
     game.player.score = 0;
     game.computer.score = 0;
     game.player.lives = 5;
    }
    
    /**
    * Draw the winner screen
    **/
    function screenWinner() {
     var center = game.canvas.width / 2;
     var height = game.canvas.height / 2;
     var header = "Game Over!";
     var score = "Score: " + game.player.score;
    
     //set the header text
     game.canvasContext.fillStyle = game.colors.header;
     game.canvasContext.font = game.fonts.header;
     var headerSize = game.canvasContext.measureText(header);
     game.canvasContext.fillText(header, center - headerSize.width/2, height);
    
     //set the score text
     game.canvasContext.fillStyle = game.colors.text;
     game.canvasContext.font = game.fonts.regular;
     var scoreSize = game.canvasContext.measureText(score);
     game.canvasContext.fillText(score, center - scoreSize.width/2, height + 25);
    }
    
    /**
    * Draw the continue screen
    **/
    function screenContinue() {
     var center = game.canvas.width / 2;
     var height = game.canvas.height / 2;
    
     //set the header text
     var header = "Missed Ball!";
     game.canvasContext.fillStyle = game.colors.header;
     game.canvasContext.font = game.fonts.header;
     var headerSize = game.canvasContext.measureText(header);
     game.canvasContext.fillText(header, center - headerSize.width/2, height);
    
     //set the info text
     var info = "Click anywhere to start the next ball";
     game.canvasContext.fillStyle = game.colors.text;
     game.canvasContext.font = game.fonts.regular;
     var infoSize = game.canvasContext.measureText(info);
     game.canvasContext.fillText(info, center - infoSize.width/2, height + 25);
    }
    
    /**
    * Draw the level up screen
    **/
    function screenLevelUp() {
     var center = game.canvas.width / 2;
     var height = game.canvas.height / 2;
    
     //set header
     var header = "Level " + game.level;
     game.canvasContext.fillStyle = game.colors.header;
     game.canvasContext.font = game.fonts.header;
     var headerSize = game.canvasContext.measureText(header);
     game.canvasContext.fillText(header, center - headerSize.width/2, height);
    
     //set the regular text color and font
     game.canvasContext.fillStyle = game.colors.text;
     game.canvasContext.font = game.fonts.regular;
    
     //set the level text
     var info = "Click anywhere to start the next ball";
     var infoSize = game.canvasContext.measureText(info);
     game.canvasContext.fillText(info, center - infoSize.width/2, height + 25);
    }
    
    /**
    * Draw the start screen
    **/
    function screenStartGame() {
     var center = game.canvas.width / 2;
     var height = game.canvas.height / 2;
    
     //set the header text
     var header = "BattlePong!";
     game.canvasContext.fillStyle = game.colors.header;
     game.canvasContext.font = game.fonts.header;
     var headerSize = game.canvasContext.measureText(header);
     game.canvasContext.fillText(header, center - headerSize.width/2, height);
    
     //set the info text
     var info = "Click anywhere to start playing";
     game.canvasContext.fillStyle = game.colors.text;
     game.canvasContext.font = game.fonts.regular;
     var infoSize = game.canvasContext.measureText(info);
     game.canvasContext.fillText(info, center - infoSize.width/2, height + 25);
    }
    
    /**
    * Buffer the screen
    **/
    function buffer() {
    
     //black out the screen
     drawRectangle(0, 0, game.canvas.width, game.canvas.height, game.colors.background);
    
     //draw one if the screens if they're active
     if (game.screens.winner) {
     screenWinner();
     return;
     }
     else if (game.screens.continue) {
     screenContinue();
     return;
     }
     else if (game.screens.levelUp) {
     screenLevelUp();
     return;
     }
     else if (game.screens.startGame) {
     screenStartGame();
     return;
     }
    
     //playing the game
     move();
     drawBoard();
    }

    Test Your File

    Open your html file in a browser. Make sure that your javascript file is located in the same place. Voila! Now you can tweak and refine it to your hearts content.

  6. There are multiple sides to every story. As far as my view point goes, I asked her to buy Vis Servo because she was not contributing to any of the work being done on it. She refused and I was unwilling to continue paying for the hosting and graphics and do all the programming on it by myself. I was supporting the site 100% and paying several hundred dollars a month to keep it running. When she said she would not sell it I dissolved the partnership and took back all the work I'd put into it. I gave her a copy of the database info that was relevant, so no, I did not delete new player information. I reverted the game to the state it was in before we became partners and took everything I had paid for.

    I would still love to get the game back up and running but since Tyrant would not sell and would not pay for the work I did I don't see that happening anytime in the future. I'm glad you liked VS, I loved it too and I would be thrilled to have it up again if she and I could come to some kind of agreement.

  7. It has to do with how computers work and how they draw graphics to a screen. That's what a render function does. They have something called a frame rate, which means how many times the screen re-draws as the monitor refreshes the content that it's displaying. This is also why if you look at a computer screen through a video recording camera lens you can see that the screen appears to flicker.

    As far as why you tend to separate input out from rendering -- this has to do with the game state. As you take in input from the user you will update the game state so that the game re-draws things in a manner that makes the graphics appear to be moving. Think of an old timey flip book where you would have to flip through the pages really fast to see the image animate over time. That's the same thing your main game loop is doing, it just has to take into account what the user has done (ie keypress or touch) before it can trigger the game state to update and re-draw everything in an updated position.

    You might find it helpful to take some computer graphics or game design classes, they will go into these principals in a much more in-depth way.

  8. I have a bunch of forest art for sale. $25 if you want the flat png files and $75 for the layered PSD files. This is not an exclusive sale, anyone who wants them can buy a copy. The set includes:

    • 3 flowers
    • 3 grasses
    • 3 trees
    • 3 logs
    • 3 rocks
    • mud pit
    • hawk
    • raven
    • moose
    • deer
    • bear
    • wolf
    • coyote
    • rabbit
    • squirrel
    • grass and sky background

     

     

    wildlife_scenery.png

  9. 7 hours ago, Zrcalo said:

    @Design1online
    are you located in the US? If you're in the US, you cant have members under 13 on your site iirc, because anything that requires agreeing to a ToS cannot be signed by anyone under 13. the law is called COPPA.

    I am in the US. I am COPPA compliant, therefore I allow people of all ages to sign up. I have some sign ups for kids as young as 6. It is possible to be COPPA compliant without getting a parent's email address but you have to follow a bunch of other rules and regulations -- if you read the COPPA legislation and websites you can figure out how.

  10. I have some simple game tutorials on my blog and there are lots of game development resoruces and online classes out there you could take and try. Just don't expect someone to be willing to walk you through how to design and develop games without paying for their time.

    My blog is http://jadendreamer.wordpress.com

    Search online for free game development courses. There are lots of sites out there to get you started.

×
×
  • Create New...