• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.

Canvas

Members
  • Content count

    107
  • Joined

  • Last visited

Community Reputation

246 Neutral

About Canvas

  • Rank
    Member
  1. Hello there,   So I have 3 platforms on a layer labelled "OneWayPlatform" when my player pressed W when they are hitting a ladder collision box I run this code Physics2D.IgnoreLayerCollision(LayerMask.NameToLayer("Default"), LayerMask.NameToLayer("OneWayPlatform"), true); this now allows the player to move up and down the ladder while also ignoring the collisions between the player and the platforms, this allows the player to move above the platform and then continue on the new platform above. Now here is my problem. When my player presses S to move down the ladder it runs the same code above however my player can't move thought the platform, they first have to press S to start going down then press A or D to move a little to the left or right and then S can be used to move down. Looking at the code of my player it seems fine it doesn't seem to notice the collision has changed. Can anyone please help.   Here is a screenshot showing my player can't move down but Default layer is ignoring OneWayPlatform layer    Just a quick update, If I press the S key once go into the scene and untick the platform my player is standing on my S button works correctly. so why is it still checking for the collision?   Just to let anyone know I fixed it.   Basically what I had to do was when I press W or S to start my character climbing a ladder I targeted my box collider and circle collider I set them to be triggers and then unset them to be triggers and it works. I think Unity is trying to save on calculations so it thinks its in the right by not recalculating the collision detection but however it is wrong :)
  2. Sorry for the late reply guys, I went on Holiday for quite a few days :D,   @GlassKnife this may seem to be the problem let me investigate   @Beernutts So basically check the X axis then check the Y axis? But lets say my ball has just fallen inside of a block, wouldn't my ball now bounce up and the opposite X direction for no reason?   @Buckeye I have changed my sf::IntRect to sf::FloatRect and it seem much better however I am still getting some odd effects, but they are happening a lot frequently
  3. Hello there GameDev community,   I am creating a small game project for myself where the player controls a ball which bounces, the player can move the ball left and right. Depending on what side the ball bounces from depends on how the ball should react, so if the ball bounces from its bottom it will bounce upwards, if from the left side it will bounce to the right and so on.   So let me explain some variables for my player, the player's width and height is 60 and its Y velocity may not be greater than 14, I have a bunch of displayObjects (displayobject is just an object with a sf::Sprite, it is a custom class of course) which are checked to see if the player collides with them.   So first off here is a screenshot of my game so you understand it graphically.   So first off I have a function that checks to see if the player is hitting any of the displayobjects, if the player is intersecting them the sf::IntRect is stored into a vector of sf::IntRects ready to be used later (They are stored because the player could hit multiple blocks) void LevelState::CheckPlayerCollisions() { std::vector<sf::IntRect> blocks; sf::IntRect playerRect(Player.XPos - 30, Player.YPos - 30, Player.Sprite.getTextureRect().width, Player.Sprite.getTextureRect().height); for (int i = 0; i < DisplayObjects.size(); i++) { sf::IntRect objectRect(DisplayObjects.at(i).XPos, DisplayObjects.at(i).YPos, DisplayObjects.at(i).Sprite.getTextureRect().width, DisplayObjects.at(i).Sprite.getTextureRect().height); if (objectRect.intersects(playerRect)) { blocks.push_back(objectRect); } } if (blocks.size() != 0) { std::cout << "Collision !" << std::endl; CollisionSide collisionSide = _mathsService.Debug(blocks, playerRect); Player.HitObjectUpdate(14, collisionSide); } } Once all of the displayObjects have been checked I call my mathsService Debug function (the function is called debug as I am testing this collision detection, once fully working I will of course rename it), this checks the player against each sf::IntRect in the vector, it works out the centre of the player and the centre of each sf::IntRect in the vector and states which one the player was closest to and which side the player ball bounces from. CollisionSide MathsService::Debug(std::vector<sf::IntRect> blocks, sf::IntRect player) { int playerXCentre = player.left + (player.width / 2); int playerYCentre = player.top + (player.height / 2); int blockId = 0; int difference = 0; CollisionSide side = CollisionSide::None; for (int i = 0; i < blocks.size(); i++) { int blockXCentre = (blocks.at(i).left + (blocks.at(i).width / 2)); int blockYCentre = (blocks.at(i).top + (blocks.at(i).height / 2)); int xDifference = playerXCentre - blockXCentre; int yDifference = playerYCentre - blockYCentre; int positiveX = 0; int positiveY = 0; if (xDifference < 0) { positiveX = xDifference * -1; } else { positiveX = xDifference; } if (yDifference < 0) { positiveY = yDifference * -1; } else { positiveY = yDifference; } //Work out which side was hit if (positiveX > positiveY) { //It is left or right if (xDifference < 0) { side = CollisionSide::Left; } else { side = CollisionSide::Right; } } else { //It is top or bottom if (yDifference < 0) { side = CollisionSide::Bottom; } else { side = CollisionSide::Top; } } if (difference != 0) { int newDifference = positiveX + positiveY; if (newDifference < difference) { difference = newDifference; blockId = i; } } else { difference = xDifference + yDifference; } } return side; } Once it goes through the vector it will return a CollisionSide which can be Top, Right, Bottom or Left, depending on that result depends on what the player does, so then I call Player.HitObjectUpdate which then forces the ball to move correctly void Player::HitObjectUpdate(int forceSet, CollisionSide side) { if (side == CollisionSide::Top) { YVelocity = 0; } else if (side == CollisionSide::Left && XSpeed > 0) { XVelocity = XVelocity * -1; XSpeed = XSpeed * -1; } else if (side == CollisionSide::Right && XSpeed < 0) { XVelocity = XVelocity * -1; XSpeed = XSpeed * -1; } else if (side == CollisionSide::Bottom) { YVelocity = forceSet; XSpeed = XVelocity; } } Now this works fine for a few seconds or even minutes but now and then the ball will get stuck in a block and do weird movement then jump out or just go off the screen, I'm really confused on how to check for this collision. I don't want to use any existing 2D c++ physics engine. If anyone can give me a hand with this or know of a better way to work out collision detection please let me know.   Also you can view a video at http://tinypic.com/r/2u90aqe/8 to see the weird out come of the ball when it collides with a block and goes inside of it.
  4. Its ok I have it working now   Here is my switch statement switch (event.type) { case sf::Event::KeyPressed: if (event.key.code == sf::Keyboard::D) { Characters.at(0).moveRight = true; } else if (event.key.code == sf::Keyboard::A) { Characters.at(0).moveLeft = true; } break; case sf::Event::KeyReleased: if (event.key.code == sf::Keyboard::D) { Characters.at(0).moveRight = false; } else if (event.key.code == sf::Keyboard::A) { Characters.at(0).moveLeft = false; } break; default: break; } Now at the moment i'm trying to swap the sprite around when Mario is moving left or moving right, this is what I have at the moment if (leftSpeed > 0) { sprite.setScale(-1.0, 1.0); } if (rightSpeed > 0) { sprite.setScale(1.0, 1.0); } it works fine when moving right, but if I am moving left and then turn right the sprite will turn straight around to the right side, I have tried to change the if statement to be if else if and then it works the other way around, where left is more dominant then right. How do I fix this?
  5. Thank you for the all the posts guys, I have looked at the my KeyboardEvent method and I have notice I wasn't using the event that is my bad, I have updated my mario to move smoothly now, but the one part I can't get my head around is the new switch statement I'm attempting to implement for my keyboard event   Here is my switch statement so far switch (event.type) { case sf::Event::KeyPressed: case sf::Keyboard::D:Characters.at(0).moveRight = true; break; case sf::Keyboard::A:Characters.at(0).moveLeft = true; break; break; case sf::Event::KeyReleased: case sf::Keyboard::D:Characters.at(0).moveRight = false; break; case sf::Keyboard::A:Characters.at(0).moveLeft = false; break; break; default: break; } I'm getting an error at the second sf::Keyboard::D and sf::Keyboard::A, the error states case label value has already appeared in this switch, how do I get around this? I want to change the a variable if a key is released.
  6. Well at the moment BeetNutts I have this has my keyboard event handler   Same as above void State::KeyboardEvent(sf::Event event) { if (state == GameStates::GS_Level1) { if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { //Set move right to true Characters.at(0).moveRight = true; } else if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { //Set move left to true Characters.at(0).moveLeft = true; } if (!sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { Characters.at(0).moveRight = false; } if (!sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { Characters.at(0).moveLeft = false; } } } Feel free to show code on how to make mine better   and here is my character update method void CharacterObject::UpdateMovement() { if (moveRight == true || moveLeft == true) { if (xSpeed < xSpeedMax) { xSpeed += xIncrease; } } if (moveRight == true) { xPos += xSpeed; } if (moveLeft == true) { xPos -= xSpeed; } if (moveLeft == false && moveRight == false) { if (xSpeed > 0) { std::cout << "X speed : " << xSpeed << std::endl; if ((xSpeed - 0.1) > 0) { xSpeed -= 0.1; } else { xSpeed = 0; } } else { xSpeed = 0; } } } At the moment the out come is pretty good, but the problem I am facing now is if I move right and hit my maxspeed, when I then press left and stop pressing right, I need to slow Mario down and then turn him around, but at the moment Mario just turns around and get's full maxspeed, trying to work out how I can deal with this. But also if i dont have right or left down my character stops moving, but the xSpeed isn't 0 yet
  7. Hey there people,   I'm creating a very simple Mario clone for myself and i'm trying to create a smooth movement for Mario, I'm using C++ and SFML for this project, This is the code I have at the moment void State::KeyboardEvent(sf::Event event) { if (state == GameStates::GS_Level1) { if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { //Set move right to true Characters.at(0).UpdateMovement(2, 0); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { //Set move left to true Characters.at(0).UpdateMovement(-2, 0); } } } This works but not smoothly at all, when the D or A key is pressed down, Mario will move once, then he will continue after about a second delay, it's like holding key down on your keyboard, it will type a letter, but if you keep it held down it will repeat that character, I'm thinking the best way is to maybe set a state, so if A key is pressed set mario state to moving left, and when a is released change the state to stopmoving and once speed is 0 set state to not moving, but i can't really find a good site explaining this and was hoping for some help from your guys,   Any idea on how I should implement this?
  8. Hello there fellow programmers, This is going to be a big question so get ready. First off I have attempted to create quite a few games with C++ and SFML, programming the functionality isn't to hard, but after a few weeks, or months or even days my structure does always seem to mess up, what I mean by that is, due to something I did way back means i have to amend something new to fix that problem but some of my old functions are using that function, this happens all the time and I completely understand it is my fault for not fully understanding the structure of my game or the program. So basically I am trying to create a simple clone of Mario Bros, so we have a title screen, a character, some enemies, a map made of blocks, score, time, lives, levels, continues, projectiles etc. So here is the my problem, using SFML i have myself a imageService, soundService and musicService, now these basically just load a file and store it inside of a map so I can call on that file when I need. But here is the main problem I have a State which has a ImageService, the state has a hero and a level, would I assign them each a image? for example hero.sprite = imageService.images["heroImg"]; would that be the best way? Second lets say if a level had some blocks, but some blocks are infront of the hero, would I have to write out my render function to say //Draw level blocks //Draw hero //Draw upper level blocks //Draw menu //etc... But then a really big important part is, the renderwindow is 800 by 600, in most computer games the user is allowed to change the size of the game, so lets say the user wants to display 1280 by 768, where would be the best place to draw the sprites differently? What about collision detection? if the view was 800 by 600 and now it is 1280 by 768 the width has go up by 1.5 and a bit and the height has changed by 168 pixels, would I save a global variable in my state which has the "ratios" of the screen? so 800 by 600 = 1:1 and 1280 by 768 = 1.6:1.28 would I then use that to modify all sprites displaying and also use that to modify collision detection? I'm just really trying to get my head around the structure of a game, does anyone have any simple links to books or articles on how to structure one, or even better a tutorial on how to structure a simple SFML game.
  9. Hello there gamedev community   At the moment i'm creating a basic 2D game with the help of SFML and good old C++. Now if you look at the image attached below, the left part is what I have so far, but the right side is something i would like to implement, now I know the image on the right is just a simple radial fill rectangle with the middle part transparent and the edges not transparent.   I'm trying to achieve a basic darkness around the edges of the screen and brightness at the centre (like a torch effect in a dungeon crawler). I feel like the openGL shader would be the best option for this, but I have to admit my skills with C++ and SFML are good enough to create this game, but my openGL shader knowledge is basically non-existent, I just wanted to ask first off, is a shader the best option for this? Second, if yes, could you provide some shader code or some information on where I can learn openGL shaders, Third, if no, could you provide why a shader would not be the best idea and how I should achieve this effect.   The effect is something similar to this, but of course my game is only in 2D not 3D and the torch would flicker.      
  10. Dezachu that all sounds good to me, but one question I do need to ask. You have stated that if the game was to get large ( or larger). clearing the vector and re-populating it would be quite heavy on process. This makes sense to me, but where you have said create a vector of GameObject and then iterate over that vector just render them. Could you try and explain this for my Level.cpp class. My level has a Hero object which will have a sprite, the Monster object will have a sprite and the Map will have a numerous amount of sprites. if each one of these have a GameObject which just holds the sprite. If I pass them back as the object, the vector will just take a copy, and when I call the Hero.Update method that update which changes the position will not even the GameObject copy in the vector. Would I have to change my vector to take pointers of GameObject? I would prefer to stay away from pointers as this will most probably cause a problem with memory management
  11. I'm in the early stages of a game I would love to create and i'm trying to work out how the game program should be structured (classes, headers etc). I'm using C++ and SFML for this project. Let me first by showing you my basic image of the structure. Don't pay attention to MainMenuState.cpp and NewGameState.cpp Game.cpp will have an instance of all those services, it will also have the MainMenuState, NewGameState and LevelState. Now here is my problem. Game.cpp will have a method that will call the RenderService.RenderWindow, I'm trying to work out exactly how I should code this method? Should I pass in an arrayList of sf::sprites? If I do this, the LevelState.cpp will need an ArrayList of sf::Sprites. which will be updated on each game step. But lets say the Hero.cpp has 1 sf::Sprite. the Map.cpp has 20 sf::sprites and Monster.cpp has 1 sf::Sprite. this would mean I have to pass 22 sf::Sprites back to the RenderService every game step (60fps). so that is 1320 sf::Sprites per second back to the RenderService. I understand game structure is a very hard thing to do and hard to implement correctly, because there isn't a "set" way. I have created a Vector which holds sf::Sprites and every time I call my Render function I clear the vector before so everything is removed for memory. This works fine. Would that be the answer? But as I stated before is passing a lot of sf::Sprites to be rendered ok?   P.S.   Here is my simple SFML program to test this #include <SFML/Graphics.hpp> #include "ImageService.h" #include "DisplayObject.h" #include "Enums.h" ImageService is; DisplayObject displayObject; int main() { sf::RenderWindow window(sf::VideoMode(1024, 768), "SFML works!"); sf::CircleShape shape(100.f); shape.setFillColor(sf::Color::Green); is.Images[image1].loadFromFile("ship1.tga"); displayObject.sprite.setTexture(is.Images[displayObject.spriteType]); std::vector<sf::Sprite> displayObjects; while (window.isOpen()) { displayObjects.clear(); displayObjects.push_back(displayObject.sprite); sf::Event event; while (window.pollEvent(event)) { if (event.type == sf::Event::Closed) window.close(); } window.clear(); window.draw(shape); //Draw out the selected sprites for (int i = 0; i < displayObjects.size(); i++) { window.draw(displayObjects.at(i)); } window.display(); } return 0; } Let me know if you would like me to explain any part of my program
  12. Hey there people,   I'm looking for a website or a program like steam where I can upload my game for free so anyone can download my game for free and play it. Just want to get my games our there and don't mine allowing people to download them for free. Is there any such website or software? My games are mostly focused around C++   Canvas
  13. Hello there fellow game dev members,   I'm planning to start a simple project which I can mess around with and with the hope of releasing it to the public. But there is one massive wall which I can not jump over or get around, I am not an artist, I can barely draw a slime... So does anyone out there have any links or files which are free to use for a game that could be released to the public? I did see at the top of this forum section "Free 2d and 3d sprites etc etc" but none of them really helped me the only one that did give me a few sprites is this one   http://www.lostgarden.com/2006/07/more-free-game-graphics.html   If anyone else has any links to sprites like these such as tiles, players, objects, enemies etc please feel free to post them, it would really help me out thanks   P.S. doesn't matter the quality 8-bit 16-bit vector everything is fine.   Also does anyone know if this is free to use? http://charas-project.net/charas2/index.php
  14. I'm creating a simple Isometric game using HTML5 and Javascript, but I can't seem to get the display to work, at the moment i have 9 tiles that have X and Y positions and the player has a X and Y position, the players X and Y properties are set to 100, and the tiles are as shown tiles[0] = new Array(3); tiles[1] = new Array(3); tiles[2] = new Array(3); tiles[0][0] = new point2D( 100, 100); tiles[0][1] = new point2D( 160, 100); tiles[0][2] = new point2D( 220, 100); tiles[1][0] = new point2D( 100, 160); tiles[1][1] = new point2D( 160, 160); tiles[1][2] = new point2D( 220, 160); tiles[2][0] = new point2D( 100, 220); tiles[2][1] = new point2D( 160, 220); tiles[2][2] = new point2D( 220, 220); Now I use this method to work out the isometric position function twoDToIso( point ) { var cords = point2D; cords.x = point.x - point.y; cords.y = (point.x + point.y) / 2; return cords; } point2D is function point2D( x, y) { this.x = x; this.y = y; } Now this i'm sure does work out the correct positioning, but here is the output  I just need to move my player position a tiny bit, but is that the best way to display my player position in the right position? Canvas
  15. I have a massive question to ask as I am really stuck on this and it would be create to get ads on my free application, ok first off I have been following this book   Beginning Android games 2011        http://www.apress.com/9781430230427   Now this book implements a very nice and simple game framework which I use (a simpler version can be found here       http://www.kilobolt.com/day-5-the-android-game-framework-part-i.html   Now this framework doesn't use any type of XML file what so ever, it uses a framebuffer to draw things onto the screen. now when the application is first started, this is the first method called which is in the AndroidGame.java   @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); boolean isPortrait = getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT; int frameBufferWidth = isPortrait ? 480: 800; int frameBufferHeight = isPortrait ? 800: 480; Bitmap frameBuffer = Bitmap.createBitmap(frameBufferWidth, frameBufferHeight, Config.RGB_565); float scaleX = (float) frameBufferWidth / getWindowManager().getDefaultDisplay().getWidth(); float scaleY = (float) frameBufferHeight / getWindowManager().getDefaultDisplay().getHeight(); renderView = new AndroidFastRenderView(this, frameBuffer); graphics = new AndroidGraphics(getAssets(), frameBuffer); fileIO = new AndroidFileIO(this); audio = new AndroidAudio(this); input = new AndroidInput(this, renderView, scaleX, scaleY); screen = getInitScreen(); setContentView(renderView); PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "MyGame"); } Where in here could i try and implement the admob banner? Also this is what a screen class looks like public LogoScreen(Game game) { super(game); } @Override public void update(float deltaTime) { Graphics g = game.getGraphics(); List<TouchEvent> touchEvents = game.getInput().getTouchEvents(); int len = touchEvents.size(); for(int i = 0; i < len; i ++) { try { TouchEvent event = (TouchEvent) touchEvents.get(i); if(event.type == TouchEvent.TOUCH_DOWN) { game.setScreen(new MainMenuScreen(game)); } } catch(IndexOutOfBoundsException io) { } } } @Override public void paint(float deltaTime) { Graphics g = game.getGraphics(); g.drawImage(Assets.logoScreen, 0, 0); } @Override public void pause() { // TODO Auto-generated method stub } @Override public void resume() { // TODO Auto-generated method stub } @Override public void dispose() { // TODO Auto-generated method stub } @Override public void backButton() { android.os.Process.killProcess(android.os.Process.myPid()); }   If I wanted to display an admob advert in the logoScreen what could i do that would work? I am really confused on how I can implement admob into my application, if any one can shine some light on this or help me that would be great   Thank you   Canvas   oohh also   Here is the code for the FastRenderView     package com.CC.framework.implementation; //Imports import com.CC.SphereFactorFree.R; import com.google.ads.AdSize; import com.google.ads.AdView; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Rect; import android.view.SurfaceHolder; import android.view.SurfaceView; public class AndroidFastRenderView extends SurfaceView implements Runnable { //Variables AndroidGame game; Bitmap framebuffer; Thread renderThread = null; SurfaceHolder holder; volatile boolean running = false; public AndroidFastRenderView(AndroidGame game, Bitmap framebuffer) { super(game); //AdView adView = (AdView)findViewById(R.id.ad); this.game = game; this.framebuffer = framebuffer; this.holder = getHolder(); } public void resume() { running = true; renderThread = new Thread(this); renderThread.start(); } public void run() { Rect dstRect = new Rect(); long startTime = System.nanoTime(); while(running) { if(!holder.getSurface().isValid()) { continue; } float deltaTime = (System.nanoTime() - startTime) / 10000000.000f; startTime = System.nanoTime(); if (deltaTime > 3.15) { deltaTime = (float) 3.15; } game.getCurrentScreen().update(deltaTime); game.getCurrentScreen().paint(deltaTime); Canvas canvas = holder.lockCanvas(); canvas.getClipBounds(dstRect); canvas.drawBitmap(framebuffer, null, dstRect, null); holder.unlockCanvasAndPost(canvas); } } public void pause() { running = false; while(true) { try { renderThread.join(); break; } catch (InterruptedException e) { // retry } } } }