I am playing around with SDL, trying to make a simple fighting game like street fighter or such, but I don't understand how to make more than one animation at once on the screen without flickering. For some reason while both players are idle on the screen they don't flicker, but for other animations the second player flickers. The code looks something like this:
Class player1:
...
void setrects_idle(SDL_Rect* clip) //loads the frames from a bmp image
{
for(int i = 0; i < 10; i ++) {
clip[i].x = 0 + i*224;
clip[i].y = 0;
clip[i].w = 224;
clip[i].h = 226;
}
}
void setrects_walkf(SDL_Rect* clip)
{
for(int i = 0; i < 11; i ++) {
clip[i].x = 0 + i*224;
clip[i].y = 0;
clip[i].w = 224;
clip[i].h = 226;
}
}
void player::idle(SDL_Surface* screen)
{
if (!other_action)
{
SDL_BlitSurface(player1_idle, &frames_idle[static_cast<int>(frame_idle)], screen, &offset);
SDL_Flip(screen);
if(frame_idle > 8)
frame_idle = 0;
else
frame_idle ++;
}
}
void player::walkf(SDL_Surface* screen)
{
other_action = true;
SDL_BlitSurface(player1_walkf, &frames_walkf[static_cast<int>(frame_walkf)], screen, &offset);
SDL_Flip(screen);
if(frame_walkf > 9)
frame_walkf = 0;
else
frame_walkf ++;
}
********************
Class player2:
void player2::idle(SDL_Surface* screen)
{
if (!other_action)
{
SDL_BlitSurface(player2_idle, &frames_idle[static_cast<int>(frame_idle)], screen, &offset);
//SDL_Flip(screen); //with this commented, there is no flicker on both players idle
if(frame_idle > 8)
frame_idle = 0;
else
frame_idle ++;
}
}
void player2::walkf(SDL_Surface* screen)
{
other_action = true;
SDL_BlitSurface(player2_walkf, &frames_walkf[static_cast<int>(frame_walkf)], screen, &offset);
SDL_Flip(screen); //if I comment this there is no animation for player2 at all. with it on, it flickers.
if(frame_walkf > 9)
frame_walkf = 0;
else
frame_walkf ++;
}
*****************************
SDL_Surface *screen;
screen = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
In the main loop:
player1.idle(screen);
player2.idle(screen);
...
case SDLK_d:
player1.b[1] = 1;
break;
case SDLK_j:
player2.b[1] = 1;
break;
...
if(player1.b[0])
player1.walkb(screen);
else
player1.return_to_idle();
if(player2.b[0])
player2.walkb(screen);
else
player2.return_to_idle();
You call several time SDL_Flip.
Into your main loop, call it juste once.
Erase background
Draw ALL objects.
Flip Once
Do not flip in your function walkf
Related
I have the below code that creates a delay in-between drawing characters from a string, this works using println() however does not work when using the text() function. The code is supposed to wait an allotted time then print the next character, I'm really not sure what I'm doing wrong.
int startTimer;
int waitTime = 500;
boolean funcRun = true;
void setup(){
size(500, 500);
startTimer = millis();
}
void draw(){
while(funcRun){
textAnim("hello");
}
}
void textAnim(String textInput){
int counter = 0;
int x = 10;
while(counter < textInput.length()){
if(millis() - startTimer>waitTime){
text(textInput.charAt(counter), x , 100);
startTimer = millis();
++counter;
x = x + 10;
}
funcRun = false;
}
}
The displayed screen is updated at the end of the draw() function. So your while loop is fully executed and the completed text is shown. You'll have to modify the code such that it will constantly refresh/redraw the screen, and updates the displayed text based on the time loop.
For example like this:
int currentTime;
int waitTime = 500;
int characters_to_display = 0;
boolean stringComplete = false;
String textInput = "Hello";
void setup() {
size(500, 500);
currentTime = millis();
}
void draw() {
// Update text to be shown. increaseCharIndex() is called while the text is not yet fully displayed
if (stringComplete == false) {
increaseCharIndex();
}
//Draw screen:
// draw background to clear screen
background(0);
// display (a substring of) the text
text(textInput.substring(0, characters_to_display), 10, 100);
}
void increaseCharIndex() {
// if the waitperiod has passed, increase the number of characters to be displayed
if (millis() - currentTime>waitTime) {
currentTime = millis();
characters_to_display++;
}
// if the full text will be shown, end the call to increaseCharIndex()
if (characters_to_display >= textInput.length())
{
stringComplete = true;
}
}
I am using below code to create tooltips.
m_ctrlToolTip.Create(this, TTS_ALWAYSTIP|TTS_BALLOON);
m_ti.cbSize = sizeof(TOOLINFO);
m_ti.uFlags = TTF_IDISHWND|TTF_TRACK|TTF_TRANSPARENT|TTF_ABSOLUTE;
m_ti.hwnd = m_hWnd;
m_ti.hinst = NULL;
m_ti.uId = (UINT)1;
m_ti.lpszText = "";;
m_ti.rect=CRect(0,0,0,0);
m_ctrlToolTip.SetMaxTipWidth(SHRT_MAX);
m_ctrlToolTip.SetDelayTime(TTDT_AUTOPOP,5000);
m_ctrlToolTip.Activate(TRUE);
void CLadIOView::OnMouseMove(UINT nFlags, CPoint point)
{
static CPoint prevPoint =0;
static CLadRemoteIOModule* pLastIO=NULL;
CLadRemoteIOModule* pLastIO1=pLastIO;
pLastIO=NULL;
bool bToolTipSet = false;
// Go thru each module already added
POSITION pos = gobjEztouchApp.m_objLadderLogic.m_objSysAttr.m_objRemoteIOModuleLst.GetHeadPosition();
for( ; pos != NULL; )
{
CLadRemoteIOModule* pIO = gobjEztouchApp.m_objLadderLogic.m_objSysAttr.m_objRemoteIOModuleLst.GetNext(pos);
// Get the rectangle for the module
CRect rectModule = GetIOModuleRect(pIO->m_nModulePosition);
if(!rectModule.PtInRect(pt)) continue;
pLastIO=pIO;
if(pLastIO1==pIO) break;
if(!m_bMouseDown && !m_bPlacingANewModule && prevPoint != pt)
{
CString sDescription, sPartNumber, sAddressRange;
GetIOModuleText2(pIO,sDescription, sPartNumber, sAddressRange);
sPartNumber.Remove('[');
sPartNumber.Remove(']');
CString sModuleDetails;
sModuleDetails.Format(_T("Position: M%d\nModule Type: %s\nModule Part No: %s"), pIO->m_nModulePosition+1, sDescription,sPartNumber);
if(pIO->GetIPSize() > 0)
sModuleDetails+=_T("\nInput Address: ")+ pIO->GetInputAdr()+_T(" - ")+pIO->GetEndInputAdr();
if(pIO->GetOPSize() > 0)
sModuleDetails+=_T("\nOutput Address: ")+ pIO->GetOutputAdr()+_T(" - ")+pIO->GetEndOutputAdr();
CPoint pp = pt-GetScrollPosition();
ClientToScreen(&pp);
m_ctrlToolTip.UpdateTipText(sModuleDetails,this,1);
m_ctrlToolTip.SendMessage(TTM_TRACKPOSITION, 0, (LPARAM)MAKELPARAM(pp.x, pp.y+16));//+16 to move the tooltip stem down
m_ctrlToolTip.SendMessage(TTM_TRACKACTIVATE, TRUE, (LPARAM)&m_ti);
//to track mouse leave abd there we can remove tooltip
TRACKMOUSEEVENT tk;
tk.cbSize = sizeof(tk);
tk.dwFlags = TME_LEAVE;
tk.hwndTrack = m_hWnd;
_TrackMouseEvent(&tk);
prevPoint = pt;
bToolTipSet = true;
}
bToolTipSet = true;
break;
}
if(!bToolTipSet)
{
m_ctrlToolTip.SendMessage(TTM_TRACKACTIVATE, FALSE, (LPARAM)&m_ti);
m_ctrlToolTip.UpdateTipText("",this,1);
m_ctrlToolTip.Pop();
}
The tooltip remains visible for very few seconds and then they disappear. I find this time too short to read some of the longer tooltips. Is there a way to increase the time they remain visible?
I tried to increase the time using setdelaytime function but it doesn't help me.
Thanks in advance.
I am trying to figure out how to use "sound off" and "sound on" images to control game sound. The code below displays a sound button but when you click on it, it mutes the sounds but adds a shaded circle over the button.
I would like some guide or how to make it switch from a sound on to a sound off image button as I am new to Unity.
Image File Names: SoundButton.psd and WhiteCircle.psd
var whiteCircle : GameObject;
var numberOfTouch : int = 0;
private var a : float = 1;
function Start() {
if (PlayerPrefs.GetInt("SoundBoolean") == 0) {
//check whether the sound is included, if turned on, then play sound.
numberOfTouch = 0;
whiteCircle.GetComponent(SpriteRenderer).enabled = false;
}
if (PlayerPrefs.GetInt("SoundBoolean") == 1) {
//check whether the sound is included, if turned off, then turn off the sound.
numberOfTouch = 1;
whiteCircle.GetComponent(SpriteRenderer).enabled = true;
}
}
function OnMouseDown () {
if (a <= 0) {
if (numberOfTouch == 0) {
//completely turn off the music.
a = 1;
numberOfTouch = 1;
gameObject.GetComponent.<AudioSource>().Play();
whiteCircle.GetComponent(SpriteRenderer).enabled = true;
PlayerPrefs.SetInt("SoundBoolean", 1);
PlayerPrefs.Save();
}
}
if (a <= 0) {
if (numberOfTouch == 1) {
//a fully turn on the music.
a = 1;
numberOfTouch = 0;
whiteCircle.GetComponent(SpriteRenderer).enabled = false;
PlayerPrefs.SetInt("SoundBoolean", 0);
PlayerPrefs.Save();
}
}
}
function Update() {
if (a >= 0) {
a -= 0.1;
}
}
As I understood correctly, you're looking for something to change the sprite on an object you have. I'm not testing my code or anything, but perhaps it can help you solve your problem.
var sprite1 : Sprite; // Drag your first sprite here
var sprite2 : Sprite; // Drag your second sprite here
var spriteRenderer : SpriteRenderer = whiteCircle.GetComponent(SpriteRenderer);
var whiteCircle : GameObject;
var numberOfTouch : int = 0;
private var a : float = 1;
function Start() {
if (PlayerPrefs.GetInt("SoundBoolean") == 0) {
//check whether the sound is included, if turned on, then play sound.
numberOfTouch = 0;
spriteRenderer.sprite = sprite2;
}
if (PlayerPrefs.GetInt("SoundBoolean") == 1) {
//check whether the sound is included, if turned off, then turn off the sound.
numberOfTouch = 1;
spriteRenderer.sprite = sprite1;
}
}
function OnMouseDown () {
if (a <= 0) {
if (numberOfTouch == 0) {
//completely turn off the music.
a = 1;
numberOfTouch = 1;
gameObject.GetComponent.<AudioSource>().Play();
spriteRenderer.sprite = sprite1;
PlayerPrefs.SetInt("SoundBoolean", 1);
PlayerPrefs.Save();
}
}
if (a <= 0) {
if (numberOfTouch == 1) {
//a fully turn on the music.
a = 1;
numberOfTouch = 0;
spriteRenderer.sprite = sprite2;
PlayerPrefs.SetInt("SoundBoolean", 0);
PlayerPrefs.Save();
}
}
}
function Update() {
if (a >= 0) {
a -= 0.1;
}
}
Basically, add two sprite points to where you can drag your image files, then replace the sprite on a certain spriterenderer (instead of turning it on and off).
I want to create a list of operation's in a grid view. For example visit this URL.
http://cdn-static.cnet.co.uk/i/product_media/40000186/nokia1616_01.jpg
You can look at this question or this page(and use LWUIT or CustomItems) or extend "canvas".In this way you need to two pictures for every operation in grid view.One for normal state and another for highlighted.Here is a simple canvas that represents 4 operations in 2*2 grid:
public class GridCanvas extends Canvas {
int highlightedRow = 0;
int highlightedColumn = 0;
Image[][] normalImageMat;
Image[][] highlightedImageMat;
Image[][] imageMat;
int gridColumnNo;
int gridRowNo;
/**
* constructor
*/
public GridCanvas() {
gridColumnNo = 2;
gridRowNo = 2;
normalImageMat = new Image[gridRowNo][gridColumnNo];
highlightedImageMat = new Image[gridRowNo][gridColumnNo];
imageMat = new Image[gridRowNo][gridColumnNo];
try {
for (int i = 0; i < gridRowNo; i++) {
for (int j = 0; j < gridColumnNo; j++) {
normalImageMat[i][j] = Image.createImage("/hello/normalImage" + i + j + ".png");
}
}
for (int i = 0; i < gridRowNo; i++) {
for (int j = 0; j < gridColumnNo; j++) {
highlightedImageMat[i][j] = Image.createImage("/hello/highlightedImage" + i + j + ".png");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* paint
*/
public void paint(Graphics g) {
g.setColor(255, 255, 255);
g.fillRect(0, 0, getWidth(), getHeight());
for (int i = 0; i < gridRowNo; i++) {
System.arraycopy(normalImageMat[i], 0, imageMat[i], 0, 2);
}
imageMat[highlightedRow][highlightedColumn] = highlightedImageMat[highlightedRow][highlightedColumn];
int width = 0;
int height = 0;
for (int i = 0; i < gridRowNo; i++) {
for (int j = 0; j < gridColumnNo; j++) {
g.drawImage(imageMat[i][j], width, height, 0);
width = width + imageMat[i][j].getWidth();
}
width = 0;
height = height + imageMat[0][0].getHeight();
}
}
/**
* Called when a key is pressed.
*/
protected void keyPressed(int keyCode) {
int gameAction = this.getGameAction(keyCode);
if (gameAction == RIGHT) {
highlightedColumn = Math.min(highlightedColumn + 1, gridColumnNo - 1);
} else if (gameAction == LEFT) {
highlightedColumn = Math.max(highlightedColumn - 1, 0);
} else if (gameAction == UP) {
highlightedRow = Math.max(0, highlightedRow - 1);
} else if (gameAction == DOWN) {
highlightedRow = Math.min(gridRowNo - 1, highlightedRow + 1);
}
repaint();
}
}
In real samples you would to detect gridColumnNo and gridRowNo due to screen and your icons dimensions.
If you can not go with LWUIT (license, library size, etc) and do not want to leave the screen rendering to LCDUI (CustomItem), you should extend Canvas.
I have shared code for an adaptive grid at http://smallandadaptive.blogspot.com.br/2010/12/touch-menu.html Feel free to use it.
At this sample all items are Strings, but you can change the TouchItem to draw Images instead.
Is there any way to create a Tab Menu in j2me?
I found a code but I am unable to understand it
In this code there is Tab Menu created which is in Canvas class and then Tab menu is created which is totally done in Canvas or painted. The only part I found difficult to grasp was the void go() method and then
When I try to draw anything above and below this code using paint method, it doesn't work - what's the problem?
Below is the code
// Tab Menu CANVAS class
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
public class TabMenuCanvas extends Canvas
{
TabMenu menu = null;
public TabMenuCanvas()
{
menu = new TabMenu(
new String[]{"Home", "News", "Community", "Your files", "Credits", "Events", "Blog", "Upload", "Forum Nokia"},
getWidth() - 20
);
}
protected void keyPressed(int key)
{
int gameAction = getGameAction(key);
if(gameAction == Canvas.RIGHT)
{
menu.goRight();
repaint();
}
else if(gameAction == Canvas.LEFT)
{
menu.goLeft();
repaint();
}
}
protected void paint(Graphics g)
{
g.translate(10, 30);
menu.paint(g);
g.translate(- 10, - 30);
}
}
// Tab Menu Class
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
public class TabMenu
{
int background = 0xffffff;
int bgColor = 0xcccccc;
int bgFocusedColor = 0x0000ff;
int foreColor = 0x000000;
int foreFocusedColor = 0xffffff;
int cornerRadius = 6;
int padding = 2;
int margin = 2;
Font font = Font.getDefaultFont();
int scrollStep = 20;
int selectedTab = 0; //selected tab index
int[] tabsWidth = null; //width of single tabs
int[] tabsLeft = null; //left X coordinate of single tabs
int tabHeight = 0; //height of tabs (equal for all tabs)
String[] tabs = null; //tab labels
int menuWidth = 0; //total menu width
int viewportWidth = 0; //visible viewport width
int viewportX = 0; //current viewport X coordinate
public TabMenu(String[] tabs, int width)
{
this.tabs = tabs;
this.viewportWidth = width;
initialize();
}
void initialize()
{
tabHeight = font.getHeight() + cornerRadius + 2 * padding; //[ same for all tabs]
menuWidth = 0;
tabsWidth = new int[tabs.length];
tabsLeft = new int[tabs.length];
for(int i = 0; i < tabsWidth.length; i++)
{
tabsWidth[i] = font.stringWidth(tabs[i]) + 2 * padding + 2 * cornerRadius;
tabsLeft[i] = menuWidth;
menuWidth += tabsWidth[i];
if(i > 0)
{
menuWidth += margin;
}
}
}
public void goRight()
{
go(+1);
}
public void goLeft()
{
go(-1);
}
private void go(int delta)
{
int newTab = Math.max(0, Math.min(tabs.length - 1, selectedTab + delta));
boolean scroll = true;
if(newTab != selectedTab && isTabVisible(newTab))
{
selectedTab = newTab;
if( (delta > 0 && tabsLeft[selectedTab] + tabsWidth[selectedTab] > viewportX + viewportWidth) ||
(delta < 0 && tabsLeft[selectedTab] < viewportX))
{
scroll = true;
}
else
{
scroll = false;
}
}
if(scroll)
{
viewportX = Math.max(0, Math.min(menuWidth - viewportWidth, viewportX + delta * scrollStep));
}
}
private boolean isTabVisible(int tabIndex)
{
return tabsLeft[tabIndex] < viewportX + viewportWidth &&
tabsLeft[tabIndex] + tabsWidth[tabIndex] >= viewportX;
}
public void paint(Graphics g)
{
int currentX = - viewportX;
g.setClip(0, 0, viewportWidth, tabHeight);
g.setColor(background);
g.fillRect(0, 0, viewportWidth, tabHeight);
for(int i = 0; i < tabs.length; i++)
{
g.setColor(i == selectedTab ? bgFocusedColor : bgColor);
g.fillRoundRect(currentX, 0, tabsWidth[i], tabHeight + cornerRadius, 2 * cornerRadius, 2 * cornerRadius);
g.setColor(i == selectedTab ? foreFocusedColor : foreColor);
g.drawString(tabs[i], currentX + cornerRadius + padding, cornerRadius + padding, Graphics.LEFT | Graphics.TOP);
currentX += tabsWidth[i] + margin;
}
}
}
When I try to draw anything above and below this code using paint method, it doesn't work
what of the paint methods you use to draw above and below? Pay attention that there are two methods named that way - first is in TabMenuCanvas, second is in TabMenu (second method is invoked from TabMenuCanvas#repaint).
whatever you would try to draw in TabMenuCanvas#paint will most likely be overwritten by setClip and fillRect when TabMenu#paint is invoked following repaint request
The only place where one can expect to be able to draw something visible seems to be in TabMenu#paint method, inside the clip area that is set there.
You can use GUI Libraries for J2ME,for example Lightweight User Interface Toolkit (LWUIT),Flemil have "tab menu".You can see list of GUI Libraries here.